码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ3155: Preprefix sum

时间:2018-03-03 21:53:56      阅读:189      评论:0      收藏:0      [点我收藏+]

标签:pac   mod   print   main   line   odi   输出   ...   space   

Description

 

Input

 

第一行给出两个整数N,M。分别表示序列长度和操作个数
接下来一行有N个数,即给定的序列a1,a2,....an
接下来M行,每行对应一个操作,格式见题目描述

 

Output

对于每个询问操作,输出一行,表示所询问的SSi的值。

 

Sample Input

5 3
1 2 3 4 5
Query 5
Modify 3 2
Query 5

Sample Output

35
32

HINT

1<=N,M<=100000,且在任意时刻0<=Ai<=100000

 

题目传送门

 

本来想用树状数组维护前缀和再枚举的。。。

神tm这和暴力好像没什么不一样啊

树状数组又不能支持区间修改

等等,好像可以用容斥原理做

c[x]=1+2+3+4+...+x

cc[x]=n*1+(n-1)*2+....+x

那么答案就是cc[x]-(n-x)*c[x];

 

代码如下:

#include<cmath>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
using namespace std;
typedef long long ll;
ll a[210000];
ll c[210000],cc[210000];
ll lowbit(ll x){return x&(-x);}
int n,m;
void change(ll x,ll d)
{
    int N=(n-x+1);
    while(x<=n)
    {
        c[x]+=d;cc[x]+=N*d;
        x+=lowbit(x);
    }
}
char st[15];
ll getsum(ll x)
{
    ll sum=0,ans=0;int N=n-x;
    while(x>=1)
    {
        sum+=cc[x],ans+=c[x];
        x-=lowbit(x);
    }
    return sum-N*ans;
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)scanf("%lld",&a[i]),change(i,a[i]);
    while(m--)
    {
        scanf("%s",st+1);
        if(st[1]==M)
        {
            ll x,y;
            scanf("%lld%lld",&x,&y);
            change(x,y-a[x]);
            a[x]=y;
        }
        else
        {
            ll x;
            scanf("%lld",&x);
            printf("%lld\n",getsum(x));
        }
    }
    return 0;
}

by_lmy

 

BZOJ3155: Preprefix sum

标签:pac   mod   print   main   line   odi   输出   ...   space   

原文地址:https://www.cnblogs.com/MT-LI/p/8503104.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!