数据结构--线段树
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 }
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 }
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 }
代码有时间补上
题意:
思路:
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 }
题意:给一个数组 再给Q个操作 每次将x y区间内的数换成z 求最后数组的和
思路:线段树的区间替换
AC代码
1 #include "iostream"
2 #include "string.h"
3 #include "stack"
4 #include "queue"
5 #include "高级数据结构线段树