题意:给你一个s3表达式并且s3已经有具体计算公式,让你求一个s4(就 是 s3*a[i] (k<i<=n) ) )%1e9+7
题解:输入的时候处理s3表达式中的 :a[i]的前缀和 ; a[i]平方的前缀和 ; a[i]3次方的前缀和 。
这样s3可以在O(1)时间内求出。 计算s3的时候有除法的模,不能直接模除,因为1e9+7为质数利用费马小定理计算逆元, 然后遍历a[i] (3<i<=n) ,最后式子用sum统计 a[i]*solve(i-1) 就是结果。
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
const int mod=1e9+7;
ll ans1[maxn],ans2[maxn],ans3[maxn],a[maxn];
ll quick_mul(ll a,ll b)
{
ll temp=a%mod,ans=1;
while(b)
{
if(b&1)
ans=(ans*temp)%mod;
temp=(temp*temp)%mod;
b>>=1;
}
return ans%mod;
}
ll ni(ll a,ll b)
{
return quick_mul(a,b-2)%mod;
}
ll solve(ll x){
ll s1=((ans1[x]*ans1[x])%mod*ans1[x])%mod;
ll s2=((3*ans2[x])%mod*ans1[x])%mod;
ll s3=((2*ans3[x])%mod);
ll s4=s1-s2+s3;
return s4*ni(6,mod)%mod;
}
int main()
{
ll n;
while(cin>>n)
{
ans1[0]=0,ans2[0]=0,ans3[0]=0;
for(int i=1;i<=n;i++)
{
cin>>a[i];
ans1[i]=(ans1[i-1]+a[i])%mod;
ans2[i]=(ans2[i-1]+(a[i]*a[i])%mod)%mod;
ans3[i]=(ans3[i-1]+((a[i]*a[i])%mod*a[i])%mod)%mod;
}
ll sum=0;
for(int i=4;i<=n;i++)
{
sum+=(a[i]*solve(i-1))%mod;
}
cout<<((sum)%mod)<<endl;
}
return 0;
}