- 总时间限制:
- 10000ms
- 单个测试点时间限制:
- 1000ms
- 内存限制:
- 262144kB
- 描述
-
给一个长为N的数列,有M次操作,每次操作是以下两种之一:
(1)修改数列中的一个数
(2)求数列中某连续一段的和
- 输入
- 第一行两个正整数N和M。
第二行N个整数表示这个数列。
接下来M行,每行开头是一个字符,若该字符为'M',则表示一个修改操作,接下来两个整数x和y,表示把x位置的值修改为y;若该字符为'Q',则表示一个询问操作,接下来两个整数x和y,表示求[x,y]这段区间的和。 - 输出
- 对每一个询问操作单独输出一行,表示答案。
- 样例输入
-
5 3 1 2 3 4 5 Q 1 5 M 2 7 Q 1 5
- 样例输出
-
15 20
- 提示
- 1<=N<=10^5,1<=M<=10^5,输入保证合法,且所有整数及答案可用带符号32位整型存储。
-
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 using namespace std; 5 const int maxn=100005; 6 int bt[maxn]; 7 int a[maxn]; 8 int n; 9 int lowbit (int x) { 10 return -x&x; 11 } 12 void btadd (int pos,int x) { 13 for (;pos<=n;pos+=lowbit(pos)) { 14 bt[pos]+=x; 15 } 16 } 17 int btsum (int pos) { 18 int ans=0; 19 for (;pos>0;pos-=lowbit(pos)) { 20 ans+=bt[pos]; 21 } 22 return ans; 23 } 24 int main() { 25 memset (bt,0,sizeof(bt)); 26 memset (a,0,sizeof(a)); 27 int m; 28 scanf ("%d%d",&n,&m); 29 for (int i=1;i<=n;i++) { 30 int tmp; 31 scanf ("%d",&tmp); 32 a[i]=tmp; 33 btadd(i,tmp); 34 } 35 for (int i=0;i<m;i++) { 36 char tmp; 37 cin>>tmp; 38 if (tmp=='M') { 39 int x,y; 40 scanf ("%d%d",&x,&y); 41 int delta=y-a[x]; 42 a[x]=y; 43 btadd(x,delta); 44 } else { 45 int x,y; 46 scanf ("%d%d",&x,&y); 47 printf ("%d ",btsum(y)-btsum(x-1)); 48 } 49 } 50 return 0; 51 }