nyoj116 士兵杀敌(二)树状数组 插点问线

士兵杀敌(二)

时间限制: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 }        

 

posted on 2013-08-08 17:22  细雨微光  阅读(398)  评论(0)    收藏  举报