您的位置:首页 > 其它

jzoj4819 算循环

2016-10-15 15:44 435 查看




首先那个程序是送给你的40分暴力.

先看一下他题意中的题意,我们发现答案其实等于这个式子

Ans=∑i∑jij(n−i+1)(m−j+1)

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

然后我们做一下变形

Ans=(∑i(n−i+1)i)∗(∑jj(m−j+1))

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

所以我们就可以考虑如何求

F(i)=∑i(n−i+1)i

将式子进行变形,得到

F(i)=(n−1)∑ii−∑ii2

然后我们有平方和式子

∑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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: