【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
*/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值