BZOJ3155Preprefix sum
3155: Preprefix sum
Time Limit: 1 Sec Memory Limit: 512 MBSubmit: 1288 Solved: 588
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
1 2 3 4 5
Query 5
Modify 3 2
Query 5
Sample Output
35
32
32
HINT
1<=N,M<=100000,且在任意时刻0<=Ai<=100000
Source
Solution
#include<bits/stdc++.h> using namespace std; #define MAXN 100001 typedef long long LL; int n,m,a[MAXN]; LL delta[MAXN<<2],sum[MAXN<<2],S[MAXN]; void read(int &x,char ch=getchar()) { for (;ch<'0' || ch>'9';ch=getchar()); for (x=0;ch>='0' && ch<='9';ch=getchar()) x=(x<<1)+(x<<3)+ch-'0'; } void build(int s,int l,int r) { int mid=(l+r)/2; if (l==r) return sum[s]=(LL)S[l],void(); build(s*2,l,mid),build(s*2+1,mid+1,r),sum[s]=sum[s*2]+sum[s*2+1]; } void pushdown(int s,int l,int r) { int mid=(l+r)/2; if (!delta[s]) return; sum[s*2]+=delta[s]*(LL)(mid-l+1),sum[s*2+1]+=delta[s]*(LL)(r-mid),delta[s*2]+=delta[s],delta[s*2+1]+=delta[s],delta[s]=0; } LL query(int s,int l,int r,int x,int y) { int mid=(l+r)/2; LL ans=0; if (x<=l && y>=r) return sum[s]; pushdown(s,l,r); if (x<=mid) ans+=query(s*2,l,mid,x,y); if (y>mid) ans+=query(s*2+1,mid+1,r,x,y); return ans; } void insert(int s,int l,int r,int x,int y,int z) { int mid=(l+r)/2; if (x<=l && y>=r) return sum[s]+=(LL)z*(r-l+1),delta[s]+=(LL)z,void(); pushdown(s,l,r); if (x<=mid) insert(s*2,l,mid,x,y,z); if (y>mid) insert(s*2+1,mid+1,r,x,y,z); sum[s]=sum[s*2]+sum[s*2+1]; } int main() { int i,x,y; char s[10]; //freopen("3155.in","r",stdin),freopen("3155.out","w",stdout); read(n),read(m); for (i=1;i<=n;++i) read(a[i]),S[i]=S[i-1]+(LL)a[i]; build(1,1,n); while (m--) { scanf("%s",s),read(x); if (s[0]=='M') read(y),insert(1,1,n,x,n,y-a[x]),a[x]=y; else printf("%lld\n",query(1,1,n,1,x)); } return 0; }