[FZYZOJ 1821] 一道果题
P1821 -- 一道果题
时间限制:1000MS
内存限制:131072KB
Description
动态单点修改 查询某段区间和。
Input Format
输入N M
第二行是N个整数 表示 初始序列.
接下来是M个询问
Q a b 表示查询[a,b]的和
M a b 表示把a位置的数替换成b
Output Format
对于每个Q 输出当前的区间和。
Sample Input
3 4 1 2 3 Q 1 2 Q 1 3 M 2 -1 Q 1 3
Sample Output
3 6 3
Hint
N,M<=100000
运行过程中所有数据均在 int / integer 范围内
【题解】
用树状数组维护即可。
1 #include<stdio.h> 2 char B[1<<15],*S=B,*T=B; 3 #define getc() (S==T&&(T=(S=B)+fread(B,1,1<<15,stdin),S==T)?0:*S++) 4 int n,m,b[100001],c[100001],a[100001]; 5 int lowbit(int x) {return x&(-x);} 6 int getint() { 7 int x=0,f=1; char ch=getc(); 8 while(ch<'0'||ch>'9') {if(ch=='-') f=-1; ch=getc();} 9 while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+ch-'0'; ch=getc();} 10 return x*f; 11 } 12 void modify(int x,int delta) { 13 while(x<=n) { 14 c[x]+=delta; 15 x+=lowbit(x); 16 } 17 } 18 int cal(int x) { 19 int ret=0; 20 while(x!=0) { 21 ret+=c[x]; 22 x-=lowbit(x); 23 } 24 return ret; 25 } 26 main() { 27 n=getint();m=getint(); 28 for (int i=1;i<=n;++i) { 29 b[i]=getint(); 30 a[i]=b[i]+a[i-1]; 31 c[i]=a[i]-a[i-lowbit(i)]; 32 } 33 while(m--) { 34 char ch=getc(); 35 if(ch=='Q') { 36 int p,q;p=getint();q=getint(); 37 printf("%d\n",cal(q)-cal(p-1)); 38 } 39 if(ch=='M') { 40 int p,q;p=getint();q=getint(); 41 int delta=q-b[p]; b[p]=q; 42 modify(p,delta); 43 } 44 } 45 }
这篇文章由TonyFang发布。
所有解释权归TonyFang所有。
Mailto: tony-fang@map-le.net