【BestCoder#16A / HDU5086】Revenge of Segment Tree

一个数列,求所有连续子序列的和的总和。


统计数列中第i个数总共累加了多少次即可,左右是对称的。。


比赛的时候交的最后一发%lld写成了%ll      233333从%d改成%lld没检查就交了...WA


Ai出现了F[i]次

F[1] = N

F[i] = (F[i-1] + n - 2*(i-1)) 

计算到中间再对称过去。注意奇偶。


/*
1 Bestcoder#16 A
2 2014/11/1
3 Ouc_Sky
*/

#include<stdio.h>
#include<algorithm>
#include<string.h>

using namespace std;

const int maxn = 447000;
const int mod = 1e9+7;
long long F[maxn/2 + 9];
long long A[maxn + 9];

int main()
{
    long long ans;
    int t;
    scanf("%d", &t);
    while(t--)
    {
        int n;
        ans = 0;
        F[0] = 0;
        scanf("%d", &n);
        for(int i = 1; i <= n; i ++ )
            scanf("%d", &A[i]);
        if (n%2 == 1)
        {
            for (int i = 1; i <= (n+1)/2; i ++ )
            {
                F[i] = (F[i-1] + n - 2*(i-1)) % mod;
                ans += A[i] * F[i] % mod;
                ans %= mod;
            }
            for (int i = 1; i <= (n-1)/2; i++ )
            {
                ans += A[n+1-i] * F[i] % mod;
                ans %= mod;
            }
        }
        else
        {
            for (int i = 1; i <= n/2; i ++ )
            {
                F[i] = (F[i-1] + n - 2*(i-1)) % mod;
                ans += A[i] * F[i] % mod;
                ans %= mod;
            }
            for (int i = 1; i <= n/2; i++ )
            {
                ans += A[n+1-i] * F[i] % mod;
                ans %= mod;
            }
        }
        //for(int j = 1; j <= n; j ++)
        //    printf("F[%d] = %llu\n",j,F[j]);
        printf("%lld\n", ans);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值