算法系列学习线段树vs树状数组 单点修改,区间查询 [kuangbin带你飞]专题七 线段树 A - 敌兵布阵

Posted shulin~

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法系列学习线段树vs树状数组 单点修改,区间查询 [kuangbin带你飞]专题七 线段树 A - 敌兵布阵相关的知识,希望对你有一定的参考价值。

https://vjudge.net/contest/66989#problem/A

单点修改,区间查询

方法一:线段树

http://www.cnblogs.com/kuangbin/archive/2011/08/15/2139834.html

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<string>
  4 #include<cstring>
  5 #include<cmath>
  6 #include<algorithm>
  7 #include<cstdlib>
  8 
  9 using namespace std;
 10 const int maxn=5e4+5;
 11 const int inf=0x3f3f3f3f;
 12 int num[maxn];
 13 int n;
 14 struct Node
 15 {
 16     int l;
 17     int r;
 18     int nSum; 
 19 }segTree[maxn<<2];
 20 
 21 void Build(int i,int l,int r)
 22 {
 23     segTree[i].l=l;
 24     segTree[i].r=r;
 25     if(l==r)
 26     {
 27         segTree[i].nSum=num[l];
 28         return;
 29     }
 30     int mid=(l+r)>>1;
 31     Build(i<<1,l,mid);
 32     Build((i<<1)|1,mid+1,r);
 33     segTree[i].nSum=segTree[i<<1].nSum+segTree[(i<<1)|1].nSum;
 34 }
 35 
 36 void Add(int i,int t,int b)
 37 {
 38     segTree[i].nSum+=b;
 39     if(segTree[i].l==segTree[i].r)
 40     {
 41         return;    
 42     }    
 43     int mid=(segTree[i].l+segTree[i].r)>>1;
 44     if(t<=mid)
 45     {
 46         Add(i<<1,t,b);
 47     }
 48     else
 49     {
 50         Add((i<<1)|1,t,b);
 51     }
 52 }
 53 
 54 int Query(int i,int l,int r)
 55 {
 56     if(segTree[i].l==l&&segTree[i].r==r)
 57     {
 58         return segTree[i].nSum;
 59     }
 60     int mid=(segTree[i].l+segTree[i].r)>>1;
 61     if(r<=mid)
 62     {
 63         return Query(i<<1,l,r);
 64     }
 65     else if(l>mid)
 66     {
 67         return Query((i<<1)|1,l,r);
 68     }
 69     else
 70     {
 71         return Query(i<<1,l,mid)+Query((i<<1)|1,mid+1,r);
 72     }
 73  } 
 74 int main()
 75 {
 76     int T;
 77     scanf("%d",&T);
 78     int kas=1;
 79     while(T--)
 80     {
 81         printf("Case %d:\\n",kas++);
 82         scanf("%d",&n);
 83         for(int i=1;i<=n;i++)
 84         {
 85             scanf("%d",&num[i]);
 86         }    
 87         Build(1,1,n);
 88         char ch[20]; 
 89         int a,b;
 90         while(scanf("%s",ch)==1&&ch[0]!=\'E\')
 91         {
 92             scanf("%d%d",&a,&b);
 93             if(ch[0]==\'Q\')
 94             {
 95                 int ans=Query(1,a,b);
 96                 printf("%d\\n",ans);
 97             }
 98             else if(ch[0]==\'A\')
 99             {
100                 Add(1,a,b);
101             }
102             else
103             {
104                 Add(1,a,-b);
105             }
106         }
107     }
108     return 0;
109  } 
View Code

方法二:树状数组

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<string>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<algorithm>
 7 #include<cstdlib>
 8 
 9 using namespace std;
10 const int maxn=5e4+5;
11 const int inf=0x3f3f3f3f;
12 int tree[maxn];
13 int n;
14 void Init()
15 {
16     memset(tree,0,sizeof(tree));
17 }
18 int lowbit(int x)
19 {
20     return x&-x;
21 }
22 
23 void Add(int i,int x)
24 {
25     while(i<=n)
26     {
27         tree[i]+=x;
28         i+=lowbit(i);
29     }
30 }
31 
32 int Query(int i)
33 {
34     int res=0;
35     while(i)
36     {
37         res+=tree[i];
38         i-=lowbit(i);
39     }
40     return res;
41  }
42   
43 void Setval(int i,int x)
44 {
45     int v=Query(i)-Query(i-1);
46     Add(i,-v);
47     Add(i,x); 
48 }
49 
50 int Query(int l,int r)
51 {
52     return Query(r)-Query(l-1);
53  } 
54 
55 int main()
56 {
57     int T;
58     scanf("%d",&T);
59     for(int kas=1;kas<=T;kas++)
60     {
61         Init();
62         scanf("%d",&n);
63         int x;
64         for(int i=1;i<=n;i++)
65         {
66             scanf("%d",&x);
67             Add(i,x);
68         }
69         printf("Case %d:\\n",kas);
70         char ch[20];
71         int a,b;
72         while(scanf("%s",ch)==1&&ch[0]!=\'E\')
73         {
74             scanf("%d%d",&a,&b);
75             if(ch[0]==\'A\')
76             {
77                 Add(a,b);
78             }
79             else if(ch[0]==\'S\')
80             {
81                 Add(a,-b);
82             }
83             else
84             {
85                 int ans=Query(a,b);
86                 printf("%d\\n",ans);
87             }
88         }
89     }
90     return 0;    
91 }
View Code

 

以上是关于算法系列学习线段树vs树状数组 单点修改,区间查询 [kuangbin带你飞]专题七 线段树 A - 敌兵布阵的主要内容,如果未能解决你的问题,请参考以下文章

树状数组学习

树状数组与线段树

专题训练8总结

线段树 建树 单点修改 点点/区间查询

树状数组

2021算法竞赛入门班第九节课线段树练习题