SPOJ Qtree系列 2/7
Posted itst
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SPOJ Qtree系列 2/7相关的知识,希望对你有一定的参考价值。
树剖裸题
注意把边权移到深度较深的点上,树剖跳的时候不要将LCA的答案统计上就行了
1 #include<stdio.h>
2 #include<string.h>
3 #define MAXN 100001
4 int read(){
5 int a = 0;
6 int f = 0;
7 char c = getchar();
8 while(!isdigit(c)){
9 if(c == ‘-‘)
10 f = 1;
11 c = getchar();
12 }
13 while(isdigit(c)){
14 a = (a << 3) + (a << 1) + (c ^ ‘0‘);
15 c = getchar();
16 }
17 return f ? -a : a;
18 }
19
20 char output[20];
21 void print(int x){
22 int dirN = 18;
23 if(x == 0)
24 fwrite("0" , sizeof(char) , 1 , stdout);
25 else{
26 if(x < 0){
27 x = -x;
28 fwrite("-" , sizeof(char) , 1 , stdout);
29 }
30 while(x){
31 output[--dirN] = x % 10 + 48;
32 x /= 10;
33 }
34 fwrite(output + dirN , 1 , strlen(output + dirN) , stdout);
35 }
36 fwrite("
" , 1 , 1 , stdout);
37 }
38
39 int max(int a , int b){
40 return a > b ? a : b;
41 }
42
43 struct node{
44 int l , r , maxN;
45 }Tree[MAXN << 2];
46 struct Edge{
47 int end , upEd , w;
48 }Ed[MAXN << 1];
49 int head[MAXN] , start[MAXN << 1] , size[MAXN] , son[MAXN] , fa[MAXN] , dep[MAXN];
50 int top[MAXN] , ind[MAXN] , rk[MAXN] , val[MAXN] , N = 0 , cntEd = 0 , ts = 0;
51
52 void addEd(int a , int b , int c){
53 Ed[++cntEd].end = b;
54 Ed[cntEd].upEd = head[a];
55 Ed[cntEd].w = c;
56 head[a] = cntEd;
57 }
58
59 void dfs1(int dir , int father , int w){
60 val[dir] = w;
61 dep[dir] = dep[fa[dir] = father] + 1;
62 size[dir] = 1;
63 int i;
64 for(i = head[dir] ; i ; i = Ed[i].upEd)
65 if(!dep[Ed[i].end]){
66 dfs1(Ed[i].end , dir , Ed[i].w);
67 size[dir] += size[Ed[i].end];
68 if(size[son[dir]] < size[Ed[i].end])
69 son[dir] = Ed[i].end;
70 }
71 }
72
73 void dfs2(int dir , int t){
74 top[dir] = t;
75 rk[ind[dir] = ++ts] = dir;
76 if(!son[dir])
77 return;
78 dfs2(son[dir] , t);
79 int i;
80 for(i = head[dir] ; i ; i = Ed[i].upEd)
81 if(Ed[i].end != fa[dir] && Ed[i].end != son[dir])
82 dfs2(Ed[i].end , Ed[i].end);
83 }
84
85 void pushup(int dir){
86 Tree[dir].maxN = max(Tree[dir << 1].maxN , Tree[dir << 1 | 1].maxN);
87 }
88
89 void init(int dir , int l , int r){
90 Tree[dir].l = l;
91 Tree[dir].r = r;
92 if(l == r)
93 Tree[dir].maxN = val[rk[l]];
94 else{
95 init(dir << 1 , l , l + r >> 1);
96 init(dir << 1 | 1 , (l + r >> 1) + 1 , r);
97 pushup(dir);
98 }
99 }
100
101 void change(int dir , int tar , int val){
102 if(Tree[dir].l == Tree[dir].r){
103 Tree[dir].maxN = val;
104 return;
105 }
106 if(Tree[dir].l + Tree[dir].r >> 1 >= tar)
107 change(dir << 1 , tar , val);
108 else
109 change(dir << 1 | 1 , tar , val);
110 pushup(dir);
111 }
112
113 int findMax(int dir , int l , int r){
114 if(Tree[dir].l >= l && Tree[dir].r <= r)
115 return Tree[dir].maxN;
116 int maxN = 0;
117 if(l <= Tree[dir].l + Tree[dir].r >> 1)
118 maxN = max(maxN , findMax(dir << 1 , l , r));
119 if(r > Tree[dir].l + Tree[dir].r >> 1)
120 maxN = max(maxN , findMax(dir << 1 | 1 , l , r));
121 return maxN;
122 }
123
124 void work(int x , int y){
125 if(x == y){
126 print(0);
127 return;
128 }
129 int tx = top[x] , ty = top[y] , maxN = -0x7fffffff;
130 while(tx != ty)
131 if(dep[tx] >= dep[ty]){
132 maxN = max(maxN , findMax(1 , ind[tx] , ind[x]));
133 x = fa[tx];
134 tx = top[x];
135 }
136 else{
137 maxN = max(maxN , findMax(1 , ind[ty] , ind[y]));
138 y = fa[ty];
139 ty = top[y];
140 }
141 if(ind[x] < ind[y])
142 maxN = max(maxN , findMax(1 , ind[x] + 1 , ind[y]));
143 if(ind[y] < ind[x])
144 maxN = max(maxN , findMax(1 , ind[y] + 1 , ind[x]));
145 print(maxN);
146 }
147
148 int cmp(int a , int b){
149 return dep[a] < dep[b] ? ind[b] : ind[a];
150 }
151
152 char s[10];
153 int main(){
154 N = read();
155 memset(head , 0 , sizeof(head));
156 cntEd = 0;
157 int i;
158 for(i = 1 ; i < N ; i++){
159 start[(i << 1) - 1] = read();
160 start[i << 1] = read();
161 int c = read();
162 addEd(start[(i << 1) - 1] , start[i << 1] , c);
163 addEd(start[i << 1] , start[(i << 1) - 1] , c);
164 }
165 dfs1(1 , 0 , 0);
166 dfs2(1 , 1);
167 init(1 , 1 , N);
168 while(scanf("%s" , s) && s[0] != ‘D‘){
169 int a = read() , b = read();
170 if(s[0] == ‘Q‘)
171 work(a , b);
172 else
173 change(1 , cmp(start[a << 1] , start[(a << 1) - 1]) , b);
174 }
175 return 0;
176 }
Qtree3
树剖裸题+1
将对应白点的叶子节点的值设为INF,黑点的叶子节点的值设为自己的编号,线段树维护$min$即可
1 #include<bits/stdc++.h>
2 #define MAXN 100001
3 using namespace std;
4
5 namespace IO{
6 const int maxn((1 << 21) + 1);
7 char ibuf[maxn], *iS, *iT, obuf[maxn], *oS = obuf, *oT = obuf + maxn - 1, c, st[55];
8 int f, tp;
9 char Getc() {
10 return (iS == iT ? (iT = (iS = ibuf) + fread(ibuf, 1, maxn, stdin), (iS == iT ? EOF : *iS++)) : *iS++);
11 }
12 void Flush() {
13 fwrite(obuf, 1, oS - obuf, stdout);
14 oS = obuf;
15 }
16 void Putc(char x) {
17 *oS++ = x;
18 if (oS == oT) Flush();
19 }
20 template <class Int> void Input(Int &x) {
21 for (f = 1, c = Getc(); c < ‘0‘ || c > ‘9‘; c = Getc()) f = c == ‘-‘ ? -1 : 1;
22 for (x = 0; c <= ‘9‘ && c >= ‘0‘; c = Getc()) x = (x << 3) + (x << 1) + (c ^ 48);
23 x *= f;
24 }
25 template <class Int> void Print(Int x) {
26 if (!x) Putc(‘0‘);
27 if (x < 0) Putc(‘-‘), x = -x;
28 while (x) st[++tp] = x % 10 + ‘0‘, x /= 10;
29 while (tp) Putc(st[tp--]);
30 }
31 void Getstr(char *s, int &l) {
32 for (c = Getc(); c < ‘a‘ || c > ‘z‘; c = Getc());
33 for (l = 0; c <= ‘z‘ && c >= ‘a‘; c = Getc()) s[l++] = c;
34 s[l] = 0;
35 }
36 void Putstr(const char *s) {
37 for (int i = 0, n = strlen(s); i < n; ++i) Putc(s[i]);
38 }
39 }
40 using namespace IO;
41
42 struct node{
43 int l , r , minN;
44 }Tree[MAXN << 2];
45 struct Edge{
46 int end , upEd;
47 }Ed[MAXN << 1];
48 int son[MAXN] , size[MAXN] , fa[MAXN] , dep[MAXN] , head[MAXN];
49 int top[MAXN] , ind[MAXN] , rk[MAXN] , N , cntEd , ts;
50
51 inline void addEd(int a , int b){
52 Ed[++cntEd].end = b;
53 Ed[cntEd].upEd = head[a];
54 head[a] = cntEd;
55 }
56
57 void dfs1(int dir , int father){
58 size[dir] = 1;
59 dep[dir] = dep[fa[dir] = father] + 1;
60 for(int i = head[dir] ; i ; i = Ed[i].upEd)
61 if(!dep[Ed[i].end]){
62 dfs1(Ed[i].end , dir);
63 size[dir] += size[Ed[i].end];
64 if(size[son[dir]] < size[Ed[i].end])
65 son[dir] = Ed[i].end;
66 }
67 }
68
69 void dfs2(int dir , int t){
70 top[dir] = t;
71 rk[ind[dir] = ++ts] = dir;
72 if(!son[dir])
73 return;
74 dfs2(son[dir] , t);
75 for(int i = head[dir] ; i ; i = Ed[i].upEd)
76 if(Ed[i].end != son[dir] && Ed[i].end != fa[dir])
77 dfs2(Ed[i].end , Ed[i].end);
78 }
79
80 inline int min(int a , int b){
81 return a < b ? a : b;
82 }
83
84 void init(int dir , int l , int r){
85 Tree[dir].l = l;
86 Tree[dir].r = r;
87 if(l == r)
88 Tree[dir].minN = 999999;
89 else{
90 init(dir << 1 , l , (l + r) >> 1);
91 init(dir << 1 | 1 , ((l + r) >> 1) + 1 , r);
92 Tree[dir].minN = min(Tree[dir << 1].minN , Tree[dir << 1 | 1].minN);
93 }
94 }
95
96 void change(int dir , int tar){
97 if(Tree[dir].l == Tree[dir].r){
98 Tree[dir].minN = Tree[dir].minN == 999999 ? Tree[dir].l : 999999;
99 return;
100 }
101 if(tar <= (Tree[dir].l + Tree[dir].r) >> 1)
102 change(dir << 1 , tar);
103 else
104 change(dir << 1 | 1 , tar);
105 Tree[dir].minN = min(Tree[dir << 1].minN , Tree[dir << 1 | 1].minN);
106 }
107
108 int findMin(int dir , int l , int r){
109 if(Tree[dir].l >= l && Tree[dir].r <= r)
110 return Tree[dir].minN;
111 int minN;
112 if(l <= (Tree[dir].l + Tree[dir].r) >> 1){
113 minN = findMin(dir << 1 , l , r);
114 if(minN != 999999)
115 return minN;
116 }
117 if(r > (Tree[dir].l + Tree[dir].r) >> 1)
118 return findMin(dir << 1 | 1 , l , r);
119 return 999999;
120 }
121
122 inline int work(int tar){
123 int minN = 999999;
124 while(top[tar] != 1){
125 minN = min(minN , findMin(1 , ind[top[tar]] , ind[tar]));
126 tar = fa[top[tar]];
127 }
128 minN = min(minN , findMin(1 , 1 , ind[tar]));
129 return minN == 999999 ? -1 : rk[minN];
130 }
131
132 int main(){
133 int N , M;
134 Input(N);
135 Input(M);
136 for(int i = 1 ; i < N ; i++){
137 int a , b;
138 Input(a);
139 Input(b);
140 addEd(a , b);
141 addEd(b , a);
142 }
143 dfs1(1 , 0);
144 dfs2(1 , 1);
145 init(1 , 1 , N);
146 while(M--){
147 int a;
148 Input(a);
149 if(a == 0){
150 Input(a);
151 change(1 , ind[a]);
152 }
153 else{
154 Input(a);
155 Print(work(a));
156 Putc(‘
‘);
157 }
158 }
159 Flush();
160 return 0;
161 }
以上是关于SPOJ Qtree系列 2/7的主要内容,如果未能解决你的问题,请参考以下文章