题解 P5686 【和积和】
题意
已知函数
求
Part 1 20pts
送分部分,留给只会模拟的人
Part 2 70pts
很显然
核心部分 code:
for(int i=1;i<=n;++i) prea[i] = prea[i-1] + a[i];
for(int i=1;i<=n;++i) preb[i] = preb[i-1] + b[i];
for(int l=1;l<=n;++l)
for(int r=l;r<=n;++r)
{
ans += (prea[r] - prea[l-1]) * (preb[r] - preb[l-1]) ;
}
考场上只想到这种做法,5min 打完跑路,时间复杂度
Part 3 100pts
对其进行拆分后可以推出公式。
以
相加后,在等式右边先加上一个
将符号为正的部分和符号为负的部分分别计算
正的部分:
负的部分可以通过因式分解得到:(
推而广之,对于任意一个
时间复杂度
code:
#include"bits/stdc++.h"
using namespace std;
int n;
long long a[500010],b[500010];
long long prea[500010],preb[500010];
long long suma,sumb;
long long ans;
#define mod 1000000007
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;++i)
{
scanf("%lld",&a[i]);
prea[i]=(prea[i-1]+a[i])%mod;
}
for(int i=1;i<=n;++i)
{
scanf("%lld",&b[i]);
preb[i]=(preb[i-1]+b[i])%mod;
}
for(int i=1;i<=n;i++)
{
(ans+=(((n+1)*prea[i])%mod)*preb[i])%=mod;
suma=(suma+prea[i])%mod;
sumb=(sumb+preb[i])%mod;
}
long long tot=(suma[n]*sumb[n])%mod;
ans=(ans-tot+mod)%mod;
printf("%lld",ans);
return 0;
}
//by fairicle