描述 Descript.
对于A1,A2,…..,AN,求
的值。
输入 Input
第1 行,1 个整数N。
第2 行,N 个整数A1,A2,…..,AN。
输出 Output
1 个整数,表示所求的值。
样例 Sample
输入数据
3
1 2 3
输出数据
36
备注 Hint
• 对于30% 的数据,3 <= N <= 500;
• 对于60% 的数据,3 <= N <= 5000;
• 对于100% 的数据,3 <= N <= 106,0 <= Ai <= 109。
来源 Source
ftiasch 普及组模拟赛 II
今天翻出来老题了…
其实就是提公因式,扔底下了。
a1a2a3+a1a2a4+a1a2a5+...+a1a2an+a2…
=a1(a2a3+a2a4+…+a2an)+a2…
记sum[i]为原数列的前缀和。
=a1( a2(sum[n]-sum[2]) + a3(sum[n]-sum[3])+ … )+a2…
=a1( a2sum[n] + a3sum[n] + a4sum[n]+ … - a2sum[2]-a3sum[3]-…-ansum[n])+a2…
=a1( sum[n](sum[n]-sum[1]) - a2sum[2]-a3sum[3]-…-ansum[n])+a2…
记s[i]为数列{a[i]*sum[i]}的前缀和
=a1( sum[n](sum[n]-sum[1]) –(s[n]-s[1]) )+a2…
于是答案就是:
Σa[i]*( sum[n]*(sum[n]-sum[i]) –(s[n]-s[i]) )
可以O(n)求出sum,s,然后O(n)求出。
一定要多模,不然很有可能溢出。
输出答案可能是负数,请加成正的再模后输出。
代码:
#include<cstdio>
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long LL;
const int SIZE=1000010;
const LL mod=1000000007;
LL num[SIZE];
LL sum[SIZE];
LL s[SIZE];
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%lld",&num[i]);
sum[i]=(sum[i-1]%mod+num[i]%mod)%mod;
s[i]=(s[i-1]%mod+(num[i]%mod*sum[i]%mod)%mod)%mod;
}
LL ans=0;
for(int i=1;i<=n;i++)
{
ans=(ans%mod+(num[i]%mod*( (sum[n]%mod*(sum[n]%mod-sum[i]%mod) %mod)%mod - (s[n]%mod-s[i]%mod)%mod )%mod)%mod)%mod;
}
printf("%lld",((6ll*ans)%mod+mod)%mod);
return 0;
}
/*
g++ prosum.cpp -o prosum.exe -Wall
*/