【Smart OJ P2485】Sum of product 简单数学

描述 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 */

你可能感兴趣的:(数学)