SPOJ Qtree系列

Qtree1

树剖裸题

注意把边权移到深度较深的点上,树剖跳的时候不要将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("\n" , 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 }
Qtree1

Qtree2

倍增小水题

  1 #include<bits/stdc++.h>
  2     //This code is written by Itst
  3     using namespace std;
  4      
  5     inline int read(){
  6         int a = 0;
  7         bool f = 0;
  8         char c = getchar();
  9         while(c != EOF && !isdigit(c)){
 10             if(c == '-')
 11                 f = 1;
 12             c = getchar();
 13         }
 14         while(c != EOF && isdigit(c)){
 15             a = (a << 3) + (a << 1) + (c ^ '0');
 16             c = getchar();
 17         }
 18         return f ? -a : a;
 19     }
 20      
 21     const int MAXN = 10010;
 22     struct Edge{
 23         int end , upEd , w;
 24     }Ed[MAXN << 1];
 25     int jump[MAXN][21][2] , head[MAXN] , dep[MAXN];
 26     int N , cntEd;
 27      
 28     inline void addEd(int a , int b , int c){
 29         Ed[++cntEd].end = b;
 30         Ed[cntEd].upEd = head[a];
 31         Ed[cntEd].w = c;
 32         head[a] = cntEd;
 33     }
 34      
 35     void dfs(int x , int f){
 36         jump[x][0][0] = f;
 37         dep[x] = dep[f] + 1;
 38         for(int i = 1 ; jump[x][i - 1][0] ; ++i){
 39             jump[x][i][0] = jump[jump[x][i - 1][0]][i - 1][0];
 40             jump[x][i][1] = jump[x][i - 1][1] + jump[jump[x][i - 1][0]][i - 1][1];
 41         }
 42         for(int i = head[x] ; i ; i = Ed[i].upEd)
 43             if(Ed[i].end != f){
 44                 jump[Ed[i].end][0][1] = Ed[i].w;
 45                 dfs(Ed[i].end , x);
 46             }
 47     }
 48      
 49     inline pair < int , int > LCA(int x , int y){
 50         int sum = 0;
 51         if(dep[x] < dep[y])
 52             swap(x , y);
 53         for(int i = 20 ; i >= 0 ; --i)
 54             if(dep[x] - (1 << i) >= dep[y]){
 55                 sum += jump[x][i][1];
 56                 x = jump[x][i][0];
 57             }
 58         if(x == y)
 59             return make_pair(x , sum);
 60         for(int i = 20 ; i >= 0 ; --i)
 61             if(jump[x][i][0] != jump[y][i][0]){
 62                 sum += jump[x][i][1] + jump[y][i][1];
 63                 x = jump[x][i][0];
 64                 y = jump[y][i][0];
 65             }
 66         return make_pair(jump[x][0][0] , sum + jump[x][0][1] + jump[y][0][1]);
 67     }
 68      
 69     inline int Kth(int x , int y , int k){
 70         int t = LCA(x , y).first;
 71         if(dep[x] - dep[t] + 1 >= k){
 72             --k;
 73             for(int i = 16 ; i >= 0 ; --i)
 74                 if(k & (1 << i))
 75                     x = jump[x][i][0];
 76             return x;
 77         }
 78         else{
 79             k = dep[x] + dep[y] - (dep[t] << 1) + 1 - k;
 80             for(int i = 16 ; i >= 0 ; --i)
 81                 if(k & (1 << i))
 82                     y = jump[y][i][0];
 83             return y;
 84         }
 85     }
 86      
 87     inline char getc(){
 88         char c = getchar();
 89         while(!isupper(c))
 90             c = getchar();
 91         return c = getchar();
 92     }
 93      
 94     int main(){
 95         for(int T = read() ; T ; --T){
 96             memset(head , 0 , sizeof(head));
 97             memset(jump , 0 , sizeof(jump));
 98             cntEd = 0;
 99             N = read();
100             for(int i = 1 ; i < N ; ++i){
101                 int a = read() , b = read() , c = read();
102                 addEd(a , b , c);
103                 addEd(b , a , c);
104             }
105             dfs(1 , 0);
106             int a , b , c;
107             bool f = 1;
108             while(f)
109                 switch(getc()){
110                 case 'I':
111                     printf("%d\n" , LCA(read() , read()).second);
112                     break;
113                 case 'T':
114                     a = read();
115                     b = read();
116                     c = read();
117                     printf("%d\n" , Kth(a , b , c));
118                     break;
119                 default:
120                     f = 0;
121                 }
122             cout << endl;
123         }
124         return 0;
125     }
Qtree2

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('\n');
157         }
158     }
159     Flush();
160     return 0;
161 }
Qtree3

Qtree4

点分树+堆,具体看这里

懒惰堆中$maintain$的时间改为询问之前$maintain$可以帮助卡常 

  1 #include<bits/stdc++.h>
  2 #define INF 0x3f3f3f3f
  3 //This code is written by Itst
  4 using namespace std;
  5 
  6 inline int read(){
  7     int a = 0;
  8     bool f = 0;
  9     char c = getchar();
 10     while(c != EOF && !isdigit(c)){
 11         if(c == '-')
 12             f = 1;
 13         c = getchar();
 14     }
 15     while(c != EOF && isdigit(c)){
 16         a = (a << 3) + (a << 1) + (c ^ '0');
 17         c = getchar();
 18     }
 19     return f ? -a : a;
 20 }
 21 
 22 const int MAXN = 100010;
 23 struct Edge{
 24     int end , upEd , w;
 25 }Ed[MAXN << 1];
 26 int head[MAXN] , fa[MAXN][20] , dis[MAXN][20] , dep[MAXN] , size[MAXN] , ST[21][MAXN << 1] , fir[MAXN] , logg2[MAXN << 1] , l[MAXN];
 27 int nowSize , minSize , minInd , ts , N , cntEd;
 28 unsigned char vis[MAXN];
 29 struct pq{
 30     priority_queue < int > now , del;
 31     inline void maintain(){
 32         while(!del.empty() && del.top() == now.top()){
 33             del.pop();
 34             now.pop();
 35         }
 36     }
 37     inline void push(int x){
 38         now.push(x);
 39     }
 40     inline void pop(int x){
 41         del.push(x);
 42     }
 43     inline int top(){
 44         maintain();
 45         return now.empty() ? -INF : now.top();
 46     }
 47     inline int sec(){
 48         maintain();
 49         if(now.empty())
 50             return -INF;
 51         int t = now.top();
 52         now.pop();
 53         maintain();
 54         int p = now.empty() ? -INF : now.top();
 55         now.push(t);
 56         return p;
 57     }
 58 }ans , cur[MAXN] , ch[MAXN];
 59 
 60 inline void addEd(int a , int b , int c){
 61     Ed[++cntEd].end = b;
 62     Ed[cntEd].upEd = head[a];
 63     Ed[cntEd].w = c;
 64     head[a] = cntEd;
 65 }
 66 
 67 void init_dfs(int now , int fa , int len){
 68     fir[now] = ++ts;
 69     ST[0][ts] = now;
 70     dep[now] = dep[fa] + 1;
 71     l[now] = len;
 72     for(int i = head[now] ; i ; i = Ed[i].upEd)
 73         if(Ed[i].end != fa){
 74             init_dfs(Ed[i].end , now , len + Ed[i].w);
 75             ST[0][++ts] = now;
 76         }
 77 }
 78 
 79 inline int cmp(int a , int b){
 80     return dep[a] < dep[b] ? a : b;
 81 }
 82 
 83 inline void init_st(){
 84     logg2[0] = -1;
 85     for(int i = 1 ; i <= N << 1 ; ++i)
 86         logg2[i] = logg2[i >> 1] + 1;
 87     for(int i = 1 ; 1 << i <= N << 1 ; ++i)
 88         for(int j = 1 ; j + (1 << i) - 1 <= N << 1 ; ++j)
 89             ST[i][j] = cmp(ST[i - 1][j] , ST[i - 1][j + (1 << (i - 1))]);
 90 }
 91 
 92 inline int LCA(int x , int y){
 93     x = fir[x];
 94     y = fir[y];
 95     if(x < y)
 96         swap(x , y);
 97     int t = logg2[x - y + 1];
 98     return cmp(ST[t][y] , ST[t][x - (1 << t) + 1]);
 99 }
100 
101 void getSize(int x){
102     vis[x] = 1;
103     ++nowSize;
104     for(int i = head[x] ; i ; i = Ed[i].upEd)
105         if(!vis[Ed[i].end])
106             getSize(Ed[i].end);
107     vis[x] = 0;
108 }
109 
110 void getRoot(int x){
111     vis[x] = size[x] = 1;
112     int maxN = 0;
113     for(int i = head[x] ; i ; i = Ed[i].upEd)
114         if(!vis[Ed[i].end]){
115             getRoot(Ed[i].end);
116             maxN = max(maxN , size[Ed[i].end]);
117             size[x] += size[Ed[i].end];
118         }
119     maxN = max(maxN , nowSize - size[x]);
120     if(maxN < minSize){
121         minSize = maxN;
122         minInd = x;
123     }
124     vis[x] = 0;
125 }
126 
127 inline int getLen(int x , int y){
128     return l[x] + l[y] - (l[LCA(x , y)] << 1);
129 }
130 
131 int init_dfz(int x , int pre){
132     nowSize = 0;
133     minSize = INF;
134     getSize(x);
135     getRoot(x);
136     x = minInd;
137     vis[x] = 1;
138     fa[x][0] = pre;
139     for(int i = 0 , p = x ; fa[x][i] ; p = fa[x][i++]){
140         dis[x][i] = getLen(x , fa[x][i]);
141         fa[x][i + 1] = fa[fa[x][i]][0];
142         ch[p].push(dis[x][i]);
143     }
144     for(int i = head[x] ; i ; i = Ed[i].upEd)
145         if(!vis[Ed[i].end])
146             cur[x].push(ch[init_dfz(Ed[i].end , x)].top());
147     cur[x].push(0);
148     cur[x].push(0);
149     ans.push(cur[x].top() + cur[x].sec());
150     vis[x] = 0;
151     return x;
152 }
153 
154 inline void init(){
155     init_dfs(1 , 0 , 0);
156     init_st();
157     init_dfz(1 , 0);
158 }
159 
160 inline void modify(int x){
161     vis[x] ^= 1;
162     if(vis[x]){
163         ans.pop(cur[x].top() + cur[x].sec());
164         cur[x].pop(0);
165         cur[x].pop(0);
166         ans.push(cur[x].top() + cur[x].sec());
167         int p = x;
168         for(int i = 0 ; fa[x][i] ; p = fa[x][i++]){
169             ans.pop(cur[fa[x][i]].top() + cur[fa[x][i]].sec());
170             cur[fa[x][i]].pop(ch[p].top());
171             ch[p].pop(dis[x][i]);
172             cur[fa[x][i]].push(ch[p].top());
173             ans.push(cur[fa[x][i]].top() + cur[fa[x][i]].sec());
174         }
175     }
176     else{
177         ans.pop(cur[x].top() + cur[x].sec());
178         cur[x].push(0);
179         cur[x].push(0);
180         ans.push(cur[x].top() + cur[x].sec());
181         int p = x;
182         for(int i = 0 ; fa[x][i] ; p = fa[x][i++]){
183             ans.pop(cur[fa[x][i]].top() + cur[fa[x][i]].sec());
184             cur[fa[x][i]].pop(ch[p].top());
185             ch[p].push(dis[x][i]);
186             cur[fa[x][i]].push(ch[p].top());
187             ans.push(cur[fa[x][i]].top() + cur[fa[x][i]].sec());
188         }
189     }
190 }
191 
192 inline void query(){
193     if(ans.top() <= -INF)
194         puts("They have disappeared.");
195     else
196         printf("%d\n" , ans.top());
197 }
198 
199 inline char getc(){
200     char c = getchar();
201     while(!isupper(c))
202         c = getchar();
203     return c;
204 }
205 
206 int main(){
207     #ifndef ONLINE_JUDGE
208     freopen("4115.in" , "r" , stdin);
209     freopen("4115.out" , "w" , stdout);
210     #endif
211     N = read();
212     for(int i = 1 ; i < N ; ++i){
213         int a = read() , b = read() , c = read();
214         addEd(a , b , c);
215         addEd(b , a , c);
216     }
217     init();
218     for(int M = read() ; M ; --M)
219         if(getc() == 'A')
220             query();
221         else
222             modify(read());
223     return 0;
224 }
Qtree4

Qtree5

点分树+堆,与$Qtree4$类似

但是并不需要像$Qtree4$维护当前分治范围到父亲的堆,因为从子树中节点走到父亲再走到当前节点必定不优

  1 #include<bits/stdc++.h>
  2 #define INF (int)1e9
  3 //This code is written by Itst
  4 using namespace std;
  5 
  6 inline int read(){
  7     int a = 0;
  8     bool f = 0;
  9     char c = getchar();
 10     while(c != EOF && !isdigit(c)){
 11         if(c == '-')
 12             f = 1;
 13         c = getchar();
 14     }
 15     while(c != EOF && isdigit(c)){
 16         a = (a << 3) + (a << 1) + (c ^ '0');
 17         c = getchar();
 18     }
 19     return f ? -a : a;
 20 }
 21 
 22 const int MAXN = 100010;
 23 struct Edge{
 24     int end , upEd;
 25 }Ed[MAXN << 1];
 26 int head[MAXN] , dep[MAXN] , fir[MAXN] , ST[21][MAXN << 1] , logg2[MAXN << 1] , fa[MAXN][20] , size[MAXN] , dis[MAXN][20];
 27 int N , nowSize , minSize , minInd , cntST , cntEd;
 28 bool vis[MAXN] , col[MAXN];
 29 struct pq{
 30     priority_queue < int , vector < int > , greater < int > > q1 , q2;
 31 
 32     inline void maintain(){
 33         while(!q1.empty() && !q2.empty() && q1.top() == q2.top()){
 34             q1.pop();
 35             q2.pop();
 36         }
 37     }
 38     
 39     inline void push(int x){
 40         q1.push(x);
 41     }
 42 
 43     inline void pop(int x){
 44         q2.push(x);
 45     }
 46 
 47     inline int top(){
 48         maintain();
 49         return q1.empty() ? INF : q1.top();
 50     }
 51     
 52 }cur[MAXN];
 53 
 54 inline void addEd(int a , int b){
 55     Ed[++cntEd].end = b;
 56     Ed[cntEd].upEd = head[a];
 57     head[a] = cntEd;
 58 }
 59 
 60 void init_dfs(int x , int pre){
 61     dep[x] = dep[pre] + 1;
 62     fir[x] = ++cntST;
 63     ST[0][cntST] = x;
 64     for(int i = head[x] ; i ; i = Ed[i].upEd)
 65         if(Ed[i].end != pre){
 66             init_dfs(Ed[i].end , x);
 67             ST[0][++cntST] = x;
 68         }
 69 }
 70 
 71 inline int cmp(int a , int b){
 72     return dep[a] < dep[b] ? a : b;
 73 }
 74 
 75 void init_st(){
 76     for(int i = 2 ; i <= cntST ; ++i)
 77         logg2[i] = logg2[i >> 1] + 1;
 78     for(int i = 1 ; 1 << i <= cntST ; ++i)
 79         for(int j = 1 ; j + (1 << i) - 1 <= cntST ; ++j)
 80             ST[i][j] = cmp(ST[i - 1][j] , ST[i - 1][j + (1 << (i - 1))]);
 81 }
 82 
 83 inline int LCA(int x , int y){
 84     x = fir[x];
 85     y = fir[y];
 86     if(x > y)
 87         swap(x , y);
 88     int t = logg2[y - x + 1];
 89     return cmp(ST[t][x] , ST[t][y - (1 << t) + 1]);
 90 }
 91 
 92 inline int calcLen(int x , int y){
 93     return dep[x] + dep[y] - (dep[LCA(x , y)] << 1);
 94 }
 95 
 96 void getSize(int x){
 97     vis[x] = 1;
 98     ++nowSize;
 99     for(int i = head[x] ; i ; i = Ed[i].upEd)
100         if(!vis[Ed[i].end])
101             getSize(Ed[i].end);
102     vis[x] = 0;
103 }
104 
105 void getRoot(int x){
106     int maxN = 0;
107     vis[x] = size[x] = 1;
108     for(int i = head[x] ; i ; i = Ed[i].upEd)
109         if(!vis[Ed[i].end]){
110             getRoot(Ed[i].end);
111             size[x] += size[Ed[i].end];
112             maxN = max(maxN , size[Ed[i].end]);
113         }
114     maxN = max(maxN , nowSize - size[x]);
115     if(maxN < minSize){
116         minSize = maxN;
117         minInd = x;
118     }
119     vis[x] = 0;
120 }
121 
122 void init_dfz(int x , int p){
123     nowSize = 0;
124     minSize = 0x7fffffff;
125     getSize(x);
126     getRoot(x);
127     x = minInd;
128     vis[x] = 1;
129     fa[x][0] = p;
130     for(int i = 0 ; fa[x][i] ; ++i){
131         fa[x][i + 1] = fa[fa[x][i]][0];
132         dis[x][i] = calcLen(x , fa[x][i]);
133     }
134     for(int i = head[x] ; i ; i = Ed[i].upEd)
135         if(!vis[Ed[i].end])
136             init_dfz(Ed[i].end , x);
137 }
138 
139 void init(){
140     init_dfs(1 , 0);
141     init_st();
142     init_dfz(1 , 0);
143 }
144 
145 inline int query(int x){
146     int minN = cur[x].top();
147     for(int i = 0 ; fa[x][i] ; ++i)
148         minN = min(minN , cur[fa[x][i]].top() + dis[x][i]);
149     return minN == INF ? -1 : minN;
150 }
151 
152 inline void modify(int x){
153     vis[x] ^= 1;
154     vis[x] ? cur[x].pop(0) : cur[x].push(0);
155     for(int i = 0 ; fa[x][i] ; ++i)
156         vis[x] ? cur[fa[x][i]].pop(dis[x][i]) : cur[fa[x][i]].push(dis[x][i]);
157 }
158 
159 int main(){
160     N = read();
161     for(int i = 1 ; i < N ; ++i){
162         int a = read() , b = read();
163         addEd(a , b);
164         addEd(b , a);
165     }
166     init();
167     for(int M = read() ; M ; --M)
168         if(read())
169             printf("%d\n" , query(read()));
170         else
171             modify(read());
172     return 0;
173 }
Qtree5

 

转载于:https://www.cnblogs.com/Itst/p/9785526.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值