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 }
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 }
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 }
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 }
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 }