Qtree1

树剖裸题

注意把边权移到深度较深的点上,树剖跳的时候不要将LCA的答案统计上就行了

  1. #include<stdio.h>
  2. #include<string.h>
  3. #define MAXN 100001
  4. int read(){
  5. ;
  6. ;
  7. char c = getchar();
  8. while(!isdigit(c)){
  9. if(c == '-')
  10. f = ;
  11. c = getchar();
  12. }
  13. while(isdigit(c)){
  14. a = (a << ) + (a << ) + (c ^ ');
  15. c = getchar();
  16. }
  17. return f ? -a : a;
  18. }
  19.  
  20. ];
  21. void print(int x){
  22. ;
  23. )
  24. fwrite( , stdout);
  25. else{
  26. ){
  27. x = -x;
  28. fwrite( , stdout);
  29. }
  30. while(x){
  31. output[--dirN] = x % + ;
  32. x /= ;
  33. }
  34. fwrite(output + dirN , , strlen(output + dirN) , stdout);
  35. }
  36. fwrite( , , 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 << ];
  46. struct Edge{
  47. int end , upEd , w;
  48. }Ed[MAXN << ];
  49. ] , size[MAXN] , son[MAXN] , fa[MAXN] , dep[MAXN];
  50. , cntEd = , ts = ;
  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] + ;
  62. size[dir] = ;
  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 << ].maxN , Tree[dir << | ].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 << , l , l + r >> );
  96. init(dir << | , (l + r >> ) + , 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. >= tar)
  107. change(dir << , tar , val);
  108. else
  109. change(dir << | , 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. ;
  117. )
  118. maxN = max(maxN , findMax(dir << , l , r));
  119. )
  120. maxN = max(maxN , findMax(dir << | , l , r));
  121. return maxN;
  122. }
  123.  
  124. void work(int x , int y){
  125. if(x == y){
  126. print();
  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( , ind[tx] , ind[x]));
  133. x = fa[tx];
  134. tx = top[x];
  135. }
  136. else{
  137. maxN = max(maxN , findMax( , ind[ty] , ind[y]));
  138. y = fa[ty];
  139. ty = top[y];
  140. }
  141. if(ind[x] < ind[y])
  142. maxN = max(maxN , findMax( , ind[x] + , ind[y]));
  143. if(ind[y] < ind[x])
  144. maxN = max(maxN , findMax( , ind[y] + , 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. ];
  153. int main(){
  154. N = read();
  155. memset(head , , sizeof(head));
  156. cntEd = ;
  157. int i;
  158. ; i < N ; i++){
  159. start[(i << ) - ] = read();
  160. start[i << ] = read();
  161. int c = read();
  162. addEd(start[(i << ) - ] , start[i << ] , c);
  163. addEd(start[i << ] , start[(i << ) - ] , c);
  164. }
  165. dfs1( , , );
  166. dfs2( , );
  167. init( , , N);
  168. ] != 'D'){
  169. int a = read() , b = read();
  170. ] == 'Q')
  171. work(a , b);
  172. else
  173. change( , cmp(start[a << ] , start[(a << ) - ]) , b);
  174. }
  175. ;
  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. ;
  7. ;
  8. char c = getchar();
  9. while(c != EOF && !isdigit(c)){
  10. if(c == '-')
  11. f = ;
  12. c = getchar();
  13. }
  14. while(c != EOF && isdigit(c)){
  15. a = (a << ) + (a << ) + (c ^ ');
  16. c = getchar();
  17. }
  18. return f ? -a : a;
  19. }
  20.  
  21. ;
  22. struct Edge{
  23. int end , upEd , w;
  24. }Ed[MAXN << ];
  25. ][] , 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][][] = f;
  37. dep[x] = dep[f] + ;
  38. ; jump[x][i - ][] ; ++i){
  39. jump[x][i][] = jump[jump[x][i - ][]][i - ][];
  40. jump[x][i][] = jump[x][i - ][] + jump[jump[x][i - ][]][i - ][];
  41. }
  42. for(int i = head[x] ; i ; i = Ed[i].upEd)
  43. if(Ed[i].end != f){
  44. jump[Ed[i].end][][] = Ed[i].w;
  45. dfs(Ed[i].end , x);
  46. }
  47. }
  48.  
  49. inline pair < int , int > LCA(int x , int y){
  50. ;
  51. if(dep[x] < dep[y])
  52. swap(x , y);
  53. ; i >= ; --i)
  54. << i) >= dep[y]){
  55. sum += jump[x][i][];
  56. x = jump[x][i][];
  57. }
  58. if(x == y)
  59. return make_pair(x , sum);
  60. ; i >= ; --i)
  61. ] != jump[y][i][]){
  62. sum += jump[x][i][] + jump[y][i][];
  63. x = jump[x][i][];
  64. y = jump[y][i][];
  65. }
  66. ][] , sum + jump[x][][] + jump[y][][]);
  67. }
  68.  
  69. inline int Kth(int x , int y , int k){
  70. int t = LCA(x , y).first;
  71. >= k){
  72. --k;
  73. ; i >= ; --i)
  74. << i))
  75. x = jump[x][i][];
  76. return x;
  77. }
  78. else{
  79. k = dep[x] + dep[y] - (dep[t] << ) + - k;
  80. ; i >= ; --i)
  81. << i))
  82. y = jump[y][i][];
  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 , , sizeof(head));
  97. memset(jump , , sizeof(jump));
  98. cntEd = ;
  99. N = read();
  100. ; i < N ; ++i){
  101. int a = read() , b = read() , c = read();
  102. addEd(a , b , c);
  103. addEd(b , a , c);
  104. }
  105. dfs( , );
  106. int a , b , c;
  107. ;
  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 = ;
  121. }
  122. cout << endl;
  123. }
  124. ;
  125. }

Qtree2

Qtree3

树剖裸题+1

将对应白点的叶子节点的值设为INF,黑点的叶子节点的值设为自己的编号,线段树维护$min$即可

  1. #include<bits/stdc++.h>
  2. #define MAXN 100001
  3. using namespace std;
  4.  
  5. namespace IO{
  6. << ) + );
  7. , c, st[];
  8. int f, tp;
  9. char Getc() {
  10. , maxn, stdin), (iS == iT ? EOF : *iS++)) : *iS++);
  11. }
  12. void Flush() {
  13. fwrite(obuf, , 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. , c = Getc(); c < : ;
  22. ; c <= ) + (x << ) + (c ^ );
  23. x *= f;
  24. }
  25. template <class Int> void Print(Int x) {
  26. ');
  27. ) Putc('-'), x = -x;
  28. + ;
  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. ; c <= 'z' && c >= 'a'; c = Getc()) s[l++] = c;
  34. s[l] = ;
  35. }
  36. void Putstr(const char *s) {
  37. , 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 << ];
  45. struct Edge{
  46. int end , upEd;
  47. }Ed[MAXN << ];
  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] = ;
  59. dep[dir] = dep[fa[dir] = father] + ;
  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 = ;
  89. else{
  90. init(dir << , l , (l + r) >> );
  91. init(dir << | , ((l + r) >> ) + , r);
  92. Tree[dir].minN = min(Tree[dir << ].minN , Tree[dir << | ].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 == ? Tree[dir].l : ;
  99. return;
  100. }
  101. )
  102. change(dir << , tar);
  103. else
  104. change(dir << | , tar);
  105. Tree[dir].minN = min(Tree[dir << ].minN , Tree[dir << | ].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. ){
  113. minN = findMin(dir << , l , r);
  114. )
  115. return minN;
  116. }
  117. )
  118. | , l , r);
  119. ;
  120. }
  121.  
  122. inline int work(int tar){
  123. ;
  124. ){
  125. minN = min(minN , findMin( , ind[top[tar]] , ind[tar]));
  126. tar = fa[top[tar]];
  127. }
  128. minN = min(minN , findMin( , , ind[tar]));
  129. ? - : rk[minN];
  130. }
  131.  
  132. int main(){
  133. int N , M;
  134. Input(N);
  135. Input(M);
  136. ; i < N ; i++){
  137. int a , b;
  138. Input(a);
  139. Input(b);
  140. addEd(a , b);
  141. addEd(b , a);
  142. }
  143. dfs1( , );
  144. dfs2( , );
  145. init( , , N);
  146. while(M--){
  147. int a;
  148. Input(a);
  149. ){
  150. Input(a);
  151. change( , ind[a]);
  152. }
  153. else{
  154. Input(a);
  155. Print(work(a));
  156. Putc('\n');
  157. }
  158. }
  159. Flush();
  160. ;
  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. ;
  8. ;
  9. char c = getchar();
  10. while(c != EOF && !isdigit(c)){
  11. if(c == '-')
  12. f = ;
  13. c = getchar();
  14. }
  15. while(c != EOF && isdigit(c)){
  16. a = (a << ) + (a << ) + (c ^ ');
  17. c = getchar();
  18. }
  19. return f ? -a : a;
  20. }
  21.  
  22. ;
  23. struct Edge{
  24. int end , upEd , w;
  25. }Ed[MAXN << ];
  26. ] , dis[MAXN][] , dep[MAXN] , size[MAXN] , ST[][MAXN << ] , fir[MAXN] , logg2[MAXN << ] , 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[][ts] = now;
  70. dep[now] = dep[fa] + ;
  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[][++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[] = -;
  85. ; i <= N << ; ++i)
  86. logg2[i] = logg2[i >> ] + ;
  87. ; << i <= N << ; ++i)
  88. ; j + ( << i) - <= N << ; ++j)
  89. ST[i][j] = cmp(ST[i - ][j] , ST[i - ][j + ( << (i - ))]);
  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. ];
  98. << t) + ]);
  99. }
  100.  
  101. void getSize(int x){
  102. vis[x] = ;
  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] = ;
  108. }
  109.  
  110. void getRoot(int x){
  111. vis[x] = size[x] = ;
  112. ;
  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] = ;
  125. }
  126.  
  127. inline int getLen(int x , int y){
  128. );
  129. }
  130.  
  131. int init_dfz(int x , int pre){
  132. nowSize = ;
  133. minSize = INF;
  134. getSize(x);
  135. getRoot(x);
  136. x = minInd;
  137. vis[x] = ;
  138. fa[x][] = pre;
  139. , p = x ; fa[x][i] ; p = fa[x][i++]){
  140. dis[x][i] = getLen(x , fa[x][i]);
  141. fa[x][i + ] = fa[fa[x][i]][];
  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();
  148. cur[x].push();
  149. ans.push(cur[x].top() + cur[x].sec());
  150. vis[x] = ;
  151. return x;
  152. }
  153.  
  154. inline void init(){
  155. init_dfs( , , );
  156. init_st();
  157. init_dfz( , );
  158. }
  159.  
  160. inline void modify(int x){
  161. vis[x] ^= ;
  162. if(vis[x]){
  163. ans.pop(cur[x].top() + cur[x].sec());
  164. cur[x].pop();
  165. cur[x].pop();
  166. ans.push(cur[x].top() + cur[x].sec());
  167. int p = x;
  168. ; 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();
  179. cur[x].push();
  180. ans.push(cur[x].top() + cur[x].sec());
  181. int p = x;
  182. ; 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. ; 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. ;
  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. ;
  8. ;
  9. char c = getchar();
  10. while(c != EOF && !isdigit(c)){
  11. if(c == '-')
  12. f = ;
  13. c = getchar();
  14. }
  15. while(c != EOF && isdigit(c)){
  16. a = (a << ) + (a << ) + (c ^ ');
  17. c = getchar();
  18. }
  19. return f ? -a : a;
  20. }
  21.  
  22. ;
  23. struct Edge{
  24. int end , upEd;
  25. }Ed[MAXN << ];
  26. ][MAXN << ] , logg2[MAXN << ] , fa[MAXN][] , size[MAXN] , dis[MAXN][];
  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] + ;
  62. fir[x] = ++cntST;
  63. ST[][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[][++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. ; i <= cntST ; ++i)
  77. logg2[i] = logg2[i >> ] + ;
  78. ; << i <= cntST ; ++i)
  79. ; j + ( << i) - <= cntST ; ++j)
  80. ST[i][j] = cmp(ST[i - ][j] , ST[i - ][j + ( << (i - ))]);
  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. ];
  89. << t) + ]);
  90. }
  91.  
  92. inline int calcLen(int x , int y){
  93. );
  94. }
  95.  
  96. void getSize(int x){
  97. vis[x] = ;
  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] = ;
  103. }
  104.  
  105. void getRoot(int x){
  106. ;
  107. vis[x] = size[x] = ;
  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] = ;
  120. }
  121.  
  122. void init_dfz(int x , int p){
  123. nowSize = ;
  124. minSize = 0x7fffffff;
  125. getSize(x);
  126. getRoot(x);
  127. x = minInd;
  128. vis[x] = ;
  129. fa[x][] = p;
  130. ; fa[x][i] ; ++i){
  131. fa[x][i + ] = fa[fa[x][i]][];
  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( , );
  141. init_st();
  142. init_dfz( , );
  143. }
  144.  
  145. inline int query(int x){
  146. int minN = cur[x].top();
  147. ; fa[x][i] ; ++i)
  148. minN = min(minN , cur[fa[x][i]].top() + dis[x][i]);
  149. : minN;
  150. }
  151.  
  152. inline void modify(int x){
  153. vis[x] ^= ;
  154. vis[x] ? cur[x].pop() : cur[x].push();
  155. ; 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. ; 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. ;
  173. }

Qtree5

SPOJ Qtree系列 5/7的更多相关文章

  1. SPOJ QTREE 系列解题报告

    题目一 : SPOJ 375 Query On a Tree http://www.spoj.com/problems/QTREE/ 给一个树,求a,b路径上最大边权,或者修改a,b边权为t. #in ...

  2. SPOJ Qtree系列

    Qtree1 将边权变为这条边连接的两个点中深度更深的点的点权,这样就可以变为带修改链上最大点权.直接树链剖分即可. 下面是一份C语言代码 #include<stdio.h> #inclu ...

  3. QTREE 树链剖分---模板 spoj QTREE

    <树链剖分及其应用> 一文讲得非常清楚,我一早上就把他学会了并且A了这题的入门题. spoj QTREE 题目: 给出一棵树,有两种操作: 1.修改一条边的边权. 2.询问节点a到b的最大 ...

  4. SPOJ GSS系列

    众所周知的仅次于ynoi的毒瘤数据结构系列.(跟Qtree系列并列?) GSS1: 长度为 $n$ 的序列 $a$,$m$ 个询问,每次询问区间 $[l,r]$ 之间的最大子段和. $1\le n,m ...

  5. 激!QTREE系列

    我现在才开始刷 QTREE 是不是太弱了?算了不管他…… QTREE: 树链剖分裸题(据说 lct 会超时……该说是真不愧有 spoj 的气息吗?) #include <cstdio> # ...

  6. QTREE系列题解

    打了快一星期的qtree终于打完了- - (其实还有两题改不出来弃疗了QAQ) orz神AK一星期前就虐完QTREE 避免忘记还是简单写下题解吧0 0 QTREE1 题意: 给出一颗带边权树 一个操作 ...

  7. SPOJ QTREE Query on a tree 树链剖分+线段树

    题目链接:http://www.spoj.com/problems/QTREE/en/ QTREE - Query on a tree #tree You are given a tree (an a ...

  8. QTREE系列题目总结

    $QTREE$ 就是一套树上数据结构练习题. 这套题貌似来源于 $SPOJ$,我是在 $luogu$ 看到的. $QTREE1$ 题意 一棵 $n$ 个点的带边权树,要求支持 单边改权值 和 询问路径 ...

  9. spoj GSS系列简要题解

    文章目录 GSS1 GSS2 GSS3 GSS4 GSS5 GSS6 GSS7 GSS8 传送门 这个GSSGSSGSS系列全部是跟子段有关的数据结构菜题. 于是来水一篇博客. GSS1 传送门 题意 ...

随机推荐

  1. JMeter 逻辑控制之While循环控制器(While Controller)

    逻辑控制之While循环控制器(While Controller)   by:授客 QQ:1033553122 测试环境 apache-jmeter-2.13 1.   添加While Control ...

  2. Linux 磁盘分区方案简析

    Linux 磁盘分区方案简析 by:授客 QQ:1033553122   磁盘分区 任何硬盘在使用前都要进行分区.硬盘的分区有两种类型:主分区和扩展分区.一个硬盘上最多只能有4个主分区,其中一个主分区 ...

  3. 编写xml文件不当时会出现R文件找不到情况

    1,先检查xml文件是否报错,报错的话直接找到报错行. 2,xml文件若不报错,可能是文本值得格式输入错误 比如android:text=“<0.5km”,此时的小于号就会引发错误,导致R文件找 ...

  4. Runtime消息动态解析与转发流程

    先上图: 下面根据具体代码看这张图. 一.创建一个Person类, Person.h #import <Foundation/Foundation.h> @interface Person ...

  5. JavaScript大杂烩6 - 理解JavaScript中的this

    在JavaScript开发中,this是很常用的一个关键字,但同时也是一个很容易引入bug的一个关键字,在这里我们就专门总结一下页面中可能出现的this关键字(包括几种在其他页面文件中出现的this) ...

  6. BD是什么角色

    BD是什么角色? 在一般创业公司里面,有了产品接下来就是运营了,而运营中很重要的一点就是BD,也就是所谓商务拓展了,俗一点说就是生意的合作拓展 https://www.jianshu.com/p/7d ...

  7. python常用模块json

    python jons模块 json模块 主要是解决数据格式的转换问题,比如python接收到json对象需要转换为python对象,供python处理,亦或者python数据需要发送到其给其他客户端 ...

  8. MIME 内容类型

    MIME内容类型 https://www.iana.org/assignments/media-types/media-types.xhtml 媒体在各浏览器的支持情况: https://develo ...

  9. pycharm的安装和使用小技巧

    一,pycharm 1,在官网下载pycharm,版本选5.0,一定要下载专业版. 2,注册方法:注册时选择 license server,填入:http://idea.qinxi1992.cn,然后 ...

  10. 利用java webservice调用天气预报实践

    最近要和其他业务系统进行数据交换,选择了webservice方案,于是查了一下网上的用法.首先是做一个天气的查询例子,看着挺简单,可实际动手做起来发现坑很多,费了半天劲终于调通了,于是记录下来. 1, ...