您的位置:首页 > 其它

【NOIP2016提高A组模拟10.15】算循环

2016-10-15 16:16 405 查看

题目



分析

一步步删掉循环,

首先,原式是∑i=1n∑j=1m∑k=in∑l=jm∑p=ik∑q=jl1

删掉最后两个循环

∑i=1n∑j=1m∑k=in∑l=jm(k−i+1)(l−j+1)

发现,当i,j固定,随着k,l的变化,(k−i+1),(l−j+1)都是每次减少1

SO,

∑i=1n∑j=1m[1+2+⋅⋅⋅+(n−i+1)][1+2+⋅⋅⋅+(m−j+1)]

再根据等差数列求和公式,

∑i=1n∑j=1m(n−i+1)(n−i+2)(m−j+1)(m−j+2)4

又发现∑ni=1(n−i+1)(n−i+2),其实就是1∗2+2∗3+3∗4+⋅⋅⋅+n∗(n+1)

设其为g(n),m类似

答案就是g(n)∗g(m)4

接着考虑求g(n)

=12+1+22+2+32+3+⋅⋅⋅+n2+n

=12+22+32+⋅⋅⋅+n2+1+2+3+⋅⋅⋅+n

根据自然数幂和得

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

#include <cmath>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <queue>
const int maxlongint=2147483647;
const long long mo=1000000007;
const int N=10000005;
using namespace std;
long long ans,n,m,ny4,ans1,ans2,ny6;
long long mi(long long x,long long y)
{
long long sum=1;
while(y)
{
if(y&1) sum=sum*x%mo;
x=x*x%mo;
y/=2;
}
return sum;
}
int main()
{
scanf("%lld%lld",&n,&m);
n%=mo;
m%=mo;
ny4=mi(4,mo-2);
ny6=mi(6,mo-2);
ans1=((n*(n+1)%mo*(2*n+1)%mo*ny6%mo)+(n+1)*n/2%mo)%mo;
ans2=((m*(m+1)%mo*(2*m+1)%mo*ny6%mo)+(m+1)*m/2%mo)%mo;
printf("%lld",ans1*ans2%mo*ny4%mo);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: