利用好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;
}