Sum of product

先观察题目所给出的数据;10^6个数据;

显然可知O( n ^ 2 )也会超时;

先根据题解写出3重暴力算法用于验证;

通过一定的推算;可以看出i和j确定时,j + 1~ n每一项的和均需要成上num[ i ] * num[ j ]求和就为题解,可优化至O(n ^ 2 ),通过预处理前m项的和,减少一次for循环;


再进行优化;最简单的优化方式,同理,优化成分段求和相乘,即仿照O(n ^ 2 )优化方法,可发现确定i和j的断点,分成相应的三段,同理区间求和相乘即可,最终可优化至O( n );


证明:

例如:给定n个数据,分别为num[ 0 ], num[ 1 ], .............num[ n ];

可以发现

            t1 = num[ i ] * (  num[ i - 1 ] * ( num[ i - 2 ] + num[ i - 3 ] + ...... + num[ 2 ] + num[ 1 ] )     + num[ i - 2 ] * ( num[ i - 3 ] + num[ 4 ] + ..... + num[ 2 ] + num[ 1 ] )  +.......... + num[ 2 ] * num[ 1 ] );

            t2 = num[ i - 1 ] * ( num[ i - 2 ] * (  num[ i - 3 ] + ........+num[ 2 ] + num[ 1 ] ) + num[ i - 3 ] * ( num[ i - 4 ] +num[ i - 5 ] + ..... +num[ 2 ] + num[ 1 ] ) + .........+num[ 2 ] * num[ 1 ] );

           。

           。

           。

           。

           。

           t( n - 2 )=  num[  3 ] * ( num[ 2 ] * num[ 1 ] );

sum = t1 + .......+ t( n - 2 );


// Sum of product.cpp : ??????????????
//

//#include "stdafx.h"
#include<iostream>
#include<cstdio>
#include<cstring>

using namespace std;

const int maxn = 1000005;
typedef long long LL;
#define Mod 1000000007
LL num[ maxn ], sum[ maxn ], dp[ maxn ];

//int _tmain(int argc, _TCHAR* argv[])
int main()
{
    int n;
    while( scanf( "%lld", &n ) != EOF  ){
        memset( sum, 0, sizeof( sum ) );
        for( int i = 1; i <= n; ++i ){
            ///cin >> num[ i ];
            scanf( "%lld", &num[ i ] );
            sum[ i ] = ( sum[ i - 1 ] + num[ i ] ) % Mod;
            if( i > 2 ){
                dp[ i ] = ( ( num[ i - 1 ] * sum[ i - 2 ] ) % Mod + dp[ i - 1 ] % Mod ) % Mod;
            }
        }
        LL ans = 0;
        for( int i = n; i > 2; --i ){
            ans += ( dp[ i ] * num[ i ] ) % Mod;
        }
        //cout << 6 * ans << endl;
        printf( "%lld\n", ( 6 * ans) % Mod );
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值