jzoj4819 算循环

来源:互联网 发布:姚明职业生涯平均数据 编辑:程序博客网 时间:2024/06/05 02:52

这里写图片描述
这里写图片描述
首先那个程序是送给你的40分暴力.
先看一下他题意中的题意,我们发现答案其实等于这个式子

Ans=ijij(ni+1)(mj+1)

就相当于对于一个点(i,j),包括他的矩阵有(n-i+1)(m-j+1)种.

然后我们做一下变形

Ans=(i(ni+1)i)(jj(mj+1))

发现这是两个形式完全相同的式子. 到了这一步我们就可以O(n)得到80分了.
所以我们就可以考虑如何求

F(i)=i(ni+1)i

将式子进行变形,得到

F(i)=(n1)iiii2

然后我们有平方和式子

ii2=n(n+1)(2n+1)/6

别问我怎么证明的,我也不知道
然后就可以O(1)求了.

#include <cstdio>#include <iostream>#define MO 1000000007#define sg(x) ((1+(x))*(x)/2%MO)using namespace std;long long n,m,ans;long long sqrtSum(long long n) {    return n*(n+1)%MO*(2*n+1)%MO*166666668%MO;}long long cnt(long long x) {    return (MO+(x+1)*sg(x)%MO-sqrtSum(x))%MO;}int main() {    freopen("loop.in","r",stdin);    freopen("loop.out","w",stdout);    cin>>n>>m;    n%=MO; m%=MO;    cout<<cnt(m)*cnt(n)%MO<<endl;}
1 0