思路:
方法一:因为已经告诉你了n个取3个的乘积和,所以可以利用这个公式递推,ans[i] = ans[i-1]+S(i-1,3)*a[i]
方法二:设 f(i, j) 表示在前 i 数里面挑 j 个乘起来的总和,那么f(i, j) = f(i − 1, j) + f(i − 1, j − 1) × ai
方法一代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
const int mod = 1e9+7;
const int maxn = 1e5+5;
ll a[maxn], n;
ll qmod(ll x, ll p)
{
ll ans = 1;
while(p)
{
if(p%2) ans = ans*x%mod;
x = x*x%mod;
p /= 2;
}
return ans;
}
int main(void)
{
while(cin >> n)
{
for(int i = 1; i <= n; i++)
scanf("%lld", &a[i]);
ll ans = 0;
ll sum1 = 0, sum2 = 0, sum3 = 0;
for(int i = 1; i <= n; i++)
{
if(n > 3)
{
ll tmp = (qmod(sum1, 3)-3*sum2%mod*sum1%mod+2*sum3%mod+mod)%mod*qmod(6, mod-2)%mod*a[i]%mod;
ans = (ans+tmp)%mod;
}
sum1 = (sum1+a[i])%mod;
sum2 = (sum2+a[i]*a[i])%mod;
sum3 = (sum3+a[i]*a[i]%mod*a[i])%mod;
}
printf("%lld\n", ans);
}
return 0;
}
方法二代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
const int maxn = 1e5+5;
const int mod = 1e9+7;
ll a[maxn], dp[maxn][5];
int main(void)
{
int n;
while(cin >> n)
{
for(int i = 1; i <= n; i++)
scanf("%lld", &a[i]);
memset(dp, 0, sizeof(dp));
dp[1][1] = a[1];
for(int i = 2; i <= n; i++)
{
for(int j = 1; j <= 4; j++)
{
if(j == 1) dp[i][j] = (dp[i-1][j]+a[i])%mod;
else dp[i][j] = (dp[i-1][j]+a[i]*dp[i-1][j-1])%mod;
}
}
printf("%lld\n", dp[n][4]);
}
return 0;
}