利用好S3的公式,枚举第4项,每次都计算S3公式中所需要的三个和,然后当i>3时每次输入a[i]时都算一遍S3,并计算a[i]*S3的值,最后加起来即可。
边加边模,防止溢出。
知识点:
快速幂取模
费马小定理
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
const int N=1e5+5;
const ll inv=166666668;//6对mod的逆元
ll POW(ll x,ll y)//快速幂取模
{
ll res=1;
while(y)
{
if(y&1)
res=(res*x)%mod;
x=(x*x)%mod;
y>>=1;
}
return res%mod;
}
ll solve(ll x,ll y,ll z)//计算此时S3的值
{
ll res=0;
res=(res+POW(x,3))%mod;
res=((res-(3*y*x%mod))%mod+mod)%mod;//防止出现负数
res=(res+2*z)%mod;
res=res*inv%mod;//除6
return res;
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
ll sum1=0,sum2=0,sum3=0;//S3公式中所需要的三个和
ll ans=0;
int a;
for(int i=1;i<=n;i++)
{
scanf("%d",&a);
if(i>3)
ans=(ans+a*solve(sum1,sum2,sum3))%mod;//代入S3的公式
sum1=(sum1+a)%mod;//求三个sum的值
sum2=(sum2+POW((ll)a,(ll)2))%mod;
sum3=(sum3+POW((ll)a,(ll)3))%mod;
}
printf("%lld\n",ans%mod);
}
return 0;
}

京公网安备 11010502036488号