士兵杀敌(二)
时间限制:1000 ms | 内存限制:65535 KB
难度:5
- 描述
-
南将军手下有N个士兵,分别编号1到N,这些士兵的杀敌数都是已知的。
小工是南将军手下的军师,南将军经常想知道第m号到第n号士兵的总杀敌数,请你帮助小工来回答南将军吧。
南将军的某次询问之后士兵i可能又杀敌q人,之后南将军再询问的时候,需要考虑到新增的杀敌数。
- 输入
- 只有一组测试数据
第一行是两个整数N,M,其中N表示士兵的个数(1<N<1000000),M表示指令的条数。(1<M<100000)
随后的一行是N个整数,ai表示第i号士兵杀敌数目。(0<=ai<=100)
随后的M行每行是一条指令,这条指令包含了一个字符串和两个整数,首先是一个字符串,如果是字符串QUERY则表示南将军进行了查询操作,后面的两个整数 m,n,表示查询的起始与终止士兵编号;如果是字符串ADD则后面跟的两个整数I,A(1<=I<=N,1<=A<=100), 表示第I个士兵新增杀敌数为A.
- 输出
- 对于每次查询,输出一个整数R表示第m号士兵到第n号士兵的总杀敌数,每组输出占一行
- 样例输入
-
5 6 1 2 3 4 5 QUERY 1 3 ADD 1 2 QUERY 1 3 ADD 2 3 QUERY 1 2 QUERY 1 5
- 样例输出
-
6 8 8 20
用树状数组来解题,用常规方法,肯定会超时,如果不知道什么是,点击,树状数组,看看,不懂的再百度;1 2 #include<cstdio> 3 #include<iostream> 4 #include<algorithm> 5 using namespace std; 6 int a[1000010]; 7 int n; 8 int lowbit(int x) 9 { 10 return x&(-x); 11 } 12 void begin()//初始化数组 13 { int t,i,j; 14 for(i=n;i>=1;i--) 15 { 16 t=0; 17 for(j=i-lowbit(i)+1;j<=i;j++) 18 t=a[j]+t; 19 a[i]=t; 20 } 21 } 22 int add(int i,int y)//在当前位置上进行添加,则后面的子数,都进行添加 23 { 24 while(i<=n) 25 { 26 a[i]=a[i]+y; 27 i=lowbit(i)+i; 28 } 29 } 30 int query(int x) 31 { 32 int sum=0;int i=x; 33 while(i>0) 34 { 35 sum=sum+a[i]; 36 i=i-lowbit(i); 37 } 38 return sum; 39 } 40 int main() 41 { 42 int m,x,y;char s[10]; 43 cin>>n>>m; 44 for(int i=1;i<=n;i++) 45 scanf("%d",&a[i]); 46 begin(); 47 while(m--) 48 { 49 cin>>s>>x>>y; 50 if(s[0]=='A') 51 add(x,y); 52 else 53 cout<<query(y)-query(x-1)<<endl; 54 } 55 return 0; 56 }