关闭

【bzoj3155】【Preprefix sum】【树状数组】

328人阅读 评论(0) 收藏 举报
分类:

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

题解:树状数组的区间修改。。。或许直接用线段树吧。。

代码:

#include<iostream>
#include<cstdio>
#define N 100010
using namespace std;
long long c[N],c2[N],a[N];
int n,q,v,x;
char ch[10];
long long read(){
    long long x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
void updata(long long c[],int x,long long v){for (int i=x;i<=n;i+=(i&(-i))) c[i]+=v;}
long long query(long long c[],int x){
  long long ans(0);
  for (int i=x;i;i-=(i&(-i))) ans+=c[i];
  return ans;
}
int main(){
  n=read();q=read();
  for (int i=1;i<=n;i++){
    a[i]=read();updata(c,i,a[i]);updata(c2,i,(n-i+1)*a[i]);
  } 
  for (int i=1;i<=q;i++){
     scanf("%s",&ch);
     if (ch[0]=='Q'){x=read();printf("%lld\n",query(c2,x)-(n-x)*query(c,x));}
     if (ch[0]=='M'){
       x=read();v=read();updata(c,x,v-a[x]);updata(c2,x,(n-x+1)*(v-a[x]));a[x]=v;
     }
  }
}


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:195622次
    • 积分:6350
    • 等级:
    • 排名:第3837名
    • 原创:455篇
    • 转载:1篇
    • 译文:0篇
    • 评论:5条
    最新评论