数据结构--线段树

Posted %%%%%

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构--线段树相关的知识,希望对你有一定的参考价值。

线段树 好久没做全部忘记了 还得重新学一下了

线段树--单点更新

HUD1166

题意:中文题

思路:线段树的单点更新

AC代码

 1 #include "iostream"
 2 #include "string.h"
 3 #include "stack"
 4 #include "queue"
 5 #include "string"
 6 #include "vector"
 7 #include "set"
 8 #include "map"
 9 #include "algorithm"
10 #include "stdio.h"
11 #include "math.h"
12 #define ll long long
13 #define mem(a) memset(a,0,sizeof(a))
14 using namespace std;
15 
16 struct Node{
17     int l,r;
18     int sum;
19 };
20 Node Tree[100000<<2];
21 
22 void Build_Tree(int root, int l, int r)
23 {
24     Tree[root].l=l;
25     Tree[root].r=r;
26     if(l==r)
27     {
28         scanf("%d",&Tree[root].sum);
29         return;
30     }
31     int mid=l+r>>1;
32     Build_Tree(root*2+1,l,mid);
33     Build_Tree(root*2+2,mid+1,r);
34     Tree[root].sum=Tree[root*2+1].sum+Tree[root*2+2].sum;
35 }
36 
37 int Query(int root,int l,int r)
38 {
39     if(Tree[root].l==l && Tree[root].r==r)
40         return Tree[root].sum;
41     int mid=Tree[root].l+Tree[root].r>>1;
42     if(r<=mid)
43         return Query(root*2+1,l,r);
44     if(l>mid)
45         return Query(root*2+2,l,r);
46     else
47         return Query(root*2+1,l,mid)+Query(root*2+2,mid+1,r);
48 }
49 
50 void Update_One(int root,int l,int r,int p,int add)
51 {
52     if(l==r)
53     {
54         Tree[root].sum += add;
55         return;
56     }
57     int mid=l+r>>1;
58     if(p<=mid)  Update_One(root*2+1,l,mid,p,add);
59     else Update_One(root*2+2,mid+1,r,p,add);
60     Tree[root].sum=Tree[root*2+1].sum + Tree[root*2+2].sum;
61 }
62 
63 int main()
64 {
65     int t,c=0,n,l,r;
66     string s;
67     scanf("%d",&t);
68     while(t--){
69             printf("Case %d:\\n",++c);
70         scanf("%d",&n);
71         mem(Tree);
72         Build_Tree(0,0,n-1);
73         while(cin>>s&&s!="End")
74         {
75             scanf("%d%d",&l,&r);
76             if(s=="Query")  printf("%d\\n",Query(0,l-1,r-1));
77             else if(s=="Add")  Update_One(0,0,n-1,l-1,r);
78             else Update_One(0,0,n-1,l-1,-r);
79         }
80     }
81    return 0;
82 }
View Code

 HDU1754

题意:中文题

思路:线段树的单点更新

AC代码

 1 #include "iostream"
 2 #include "string.h"
 3 #include "stack"
 4 #include "queue"
 5 #include "string"
 6 #include "vector"
 7 #include "set"
 8 #include "map"
 9 #include "algorithm"
10 #include "stdio.h"
11 #include "math.h"
12 #define ll long long
13 #define mem(a) memset(a,0,sizeof(a))
14 using namespace std;
15 
16 struct Node{
17     int l,r;
18     int m;
19 };
20 
21 int date,p;
22 Node Tree[222222<<2];
23 
24 void Build_Tree(int root, int l, int r)
25 {
26     Tree[root].l=l;
27     Tree[root].r=r;
28     if(l==r)
29     {
30         scanf("%d",&Tree[root].m);
31         return;
32     }
33     int mid=l+r>>1;
34     Build_Tree(root*2,l,mid);
35     Build_Tree(root*2+1,mid+1,r);
36     Tree[root].m = max(Tree[root*2].m,Tree[root*2+1].m);
37 }
38 
39 int Query(int root, int l, int r)
40 {
41     if(Tree[root].l==l && Tree[root].r==r)
42         return Tree[root].m;
43     int mid=Tree[root].l+Tree[root].r>>1;
44     if(r<=mid)
45         return Query(root*2,l,r);
46     if(l>mid)
47         return Query(root*2+1,l,r);
48     else
49         return max(Query(root*2,l,mid),Query(root*2+1,mid+1,r));
50 }
51 
52 void Update_One(int root,int l,int r)
53 {
54     if(l==r)
55     {
56         Tree[root].m=date;
57         return;
58     }
59     int mid=l+r>>1;
60     if(p<=mid)  Update_One(root*2,l,mid);
61     else  Update_One(root*2+1,mid+1,r);
62     Tree[root].m = max(Tree[root*2].m,Tree[root*2+1].m);
63 }
64 
65 int main()
66 {
67     int n,q,l,r;
68     char c;
69     while(~scanf("%d%d",&n,&q)){
70         Build_Tree(1,1,n);
71         while(q--){
72             getchar();
73             scanf("%c%d%d",&c,&l,&r);
74             if(c==\'Q\')  printf("%d\\n",Query(1,l,r));
75             else  {p=l,date=r;Update_One(1,1,n);}
76         }
77     }
78    return 0;
79 }
View Code

HUD1556

题意:输入n 然后n个区间操作 l,r 对区间的气球涂油漆 ,最后输出每个气球被涂了多少次

思路:线段树的区间更新

AC代码

 1 #include "iostream"
 2 #include "string.h"
 3 #include "stack"
 4 #include "queue"
 5 #include "string"
 6 #include "vector"
 7 #include "set"
 8 #include "map"
 9 #include "algorithm"
10 #include "stdio.h"
11 #include "math.h"
12 #define ll long long
13 #define lson l,mid,rt<<1
14 #define rson mid+1,r,rt<<1|1
15 #define len (Tr[rt].r-Tr[rt].l+1)
16 #define mem(a) memset(a,0,sizeof(a))
17 using namespace std;
18 
19 struct Node{
20     int l,r;
21     int v,add;
22 };
23 Node Tr[200005<<2];
24 
25 void Push_up(int rt){
26     Tr[rt].v=Tr[rt<<1].v+Tr[rt<<1|1].v;
27 }
28 
29 void Push_Down(int rt, int m){
30     Tr[rt<<1].add+=Tr[rt].add;
31     Tr[rt<<1|1].add+=Tr[rt].add;
32     Tr[rt<<1].v+=Tr[rt].add*(m-(m>>1));
33     Tr[rt<<1|1].v+=Tr[rt].add*(m>>1);
34     Tr[rt].add=0;
35 }
36 
37 void Build_Tree(int l,int r,int rt){
38     Tr[rt].l=l,Tr[rt].r=r;
39     if(l==r) return;
40     int mid=l+r>>1;
41     Build_Tree(lson);
42     Build_Tree(rson);
43     Push_up(rt);
44 }
45 
46 void Updata(int l,int r,int rt){
47     if(l==Tr[rt].l && r==Tr[rt].r){
48         Tr[rt].v+=len;
49         Tr[rt].add++;
50         return;
51     }
52     int mid=Tr[rt].l+Tr[rt].r>>1;
53     if(r<=mid) Updata(l,r,rt<<1);
54     else if(l>mid) Updata(l,r,rt<<1|1);
55     else{
56         Updata(lson);
57         Updata(rson);
58     }
59     Push_up(rt);
60 }
61 
62 int Query(int l,int r,int rt){
63     if(l==Tr[rt].l && r==Tr[rt].r) return Tr[rt].v;
64     if(Tr[rt].add!=0) Push_Down(rt,len);
65     int mid=Tr[rt].l+Tr[rt].r>>1;
66     if(r<=mid) return Query(l,r,rt<<1);
67     if(l>mid) return Query(l,r,rt<<1|1);
68     else return Query(l,mid,rt<<1)+Query(mid+1,r,rt<<1|1);
69 }
70 
71 int main(){
72     int n,q,l,r;
73     while(scanf("%d",&n) && n!=0){
74         mem(Tr);
75         Build_Tree(1,n,1);
76         q=n;
77         while(q--){
78             scanf("%d%d",&l,&r);
79             Updata(l,r,1);
80         }
81         for(int i=1; i<=n; i++){
82             if(i!=1) printf(" ");
83             printf("%d",Query(i,i,1));
84         }
85         printf("\\n");
86     }
87     return 0;
88 }
View Code

代码有时间补上

HDU1394

HDU2795

题意:

思路:

 AC代码

 1 #include "iostream"
 2 #include "string.h"
 3 #include "stack"
 4 #include "queue"
 5 #include "string"
 6 #include "vector"
 7 #include "set"
 8 #include "map"
 9 #include "algorithm"
10 #include "stdio.h"
11 #include "math.h"
12 #define ll long long
13 #define lson l,mid,rt<<1
14 #define rson mid+1,r,rt<<1|1
15 #define len (Tr[rt].r-Tr[rt].l+1)
16 #define mem(a) memset(a,0,sizeof(a))
17 using namespace std;
18 const int N=200005;
19 struct Node{
20     int l,r;
21     int maxn;
22 }Tr[N<<2];
23 int w,ans[N];
24 
25 void Push_up(int rt){
26     Tr[rt].maxn=max(Tr[rt<<1].maxn,Tr[rt<<1|1].maxn);
27 }
28 
29 void Build_Tree(int l, int r, int rt){
30     Tr[rt].l=l,Tr[rt].r=r;
31     if(l==r){
32         Tr[rt].maxn=w; return;
33     }
34     int mid=l+r>>1;
35     Build_Tree(lson);
36     Build_Tree(rson);
37     Push_up(rt);
38 }
39 
40 void Updata_One(int l,int r,int rt,int data,int n){
41     int mid=l+r>>1;
42     if(Tr[rt].maxn<data) {ans[n]=-1;return;}
43     else if(l==r){
44         Tr[rt].maxn-=data;
45        ans[n]=Tr[rt].l;
46        return;
47     }
48     else if(Tr[rt<<1].maxn>=data)
49         Updata_One(lson,data,n);
50     else if(Tr[rt<<1|1].maxn>=data)
51         Updata_One(rson,data,n);
52     Push_up(rt);
53 }
54 
55 int main(){
56     int h,n,x;
57     while(scanf("%d%d%d",&h,&w,&n)!=EOF){
58         mem(Tr),mem(ans);
59         h = h < N ? h : N;
60         Build_Tree(1,h,1);
61         for(int i=1; i<=n; i++){
62             scanf("%d",&x);
63             Updata_One(1,h,1,x,i); printf("%d\\n",ans[i]);
64         }
65     }
66    return 0;
67 }
View Code

HDU1698

题意:给一个数组 再给Q个操作 每次将x y区间内的数换成z 求最后数组的和

思路:线段树的区间替换

AC代码

 1 #include "iostream"
 2 #include "string.h"
 3 #include "stack"
 4 #include "queue"
 5 #include "高级数据结构线段树

数据结构——线段树(C++)

线段树

数据结构线段树笔记2

数据结构--线段树

[数据结构] 主席树初识(理论,代码待补)