NYOJ116 士兵杀敌(二)线段树

解题思路:

先用数组累计从1~n的杀敌数,所以从i~j的杀敌数就是sum[j]-sum[i-1];

进行加的时候再用线段树进行单点更新m次时间复杂度就是O(mlogn)

查找时先从累加数组中计算出最开始的杀敌数再去线段树中计算后来的杀敌数

m次时间复杂度就是O(mlogn)

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <cstring>
 4 struct node
 5 {
 6     int l,r;
 7     int sum;
 8     int mid()
 9     {
10         return (l+r)/2;
11     }
12 };
13 int num[1000005];
14 node t[4000005];
15 int n,q;
16 int ans=0;
17 void init(int root,int l,int r)
18 {
19     t[root].l=l;
20     t[root].r=r;
21     t[root].sum=0;
22     if(l==r) return;
23     else
24     {
25         init(2*root+1,l,t[root].mid());
26         init(2*root+2,t[root].mid()+1,r);
27     }
28 }
29 void in(int root,int i,int num)
30 {
31     t[root].sum+=num;
32     if(i==t[root].l&&i==t[root].r) return;
33     else if(i<=t[root].mid())
34         in(2*root+1,i,num);
35     else
36         in(2*root+2,i,num);
37 }
38 void qu(int root,int l,int r)
39 {
40     if(t[root].l==l&&t[root].r==r)
41     {
42         ans+=t[root].sum;
43         return;
44     }
45     if(r<=t[root].mid())
46     {
47         qu(2*root+1,l,r);
48     }
49     else if(l>t[root].mid())
50     {
51         qu(2*root+2,l,r);
52     }
53     else
54     {
55         qu(2*root+1,l,t[root].mid());
56         qu(2*root+2,t[root].mid()+1,r);
57     }
58 }
59 
60 int main()
61 {
62     scanf("%d",&n);
63     scanf("%d",&q);
64     init(0,1,n);
65     memset(num,0,sizeof(num));
66     for(int i=1;i<=n;i++)
67     {
68         scanf("%d",&num[i]);
69         num[i]=num[i]+num[i-1];
70     }
71     char str[15];
72     int a,b;
73     for(int i=0;i<q;i++)
74     {
75         scanf("%s",str);
76         if(str[0]=='A')
77         {
78             scanf("%d%d",&a,&b);
79             in(0,a,b);
80         }
81         if(str[0]=='Q')
82         {
83             ans=0;
84             scanf("%d%d",&a,&b);
85             qu(0,a,b);
86             printf("%d\n",ans+num[b]-num[a-1]);
87         }
88     }
89 }

 

posted @ 2017-04-22 10:24  Kearon  阅读(165)  评论(0编辑  收藏  举报