记录编号 284279 评测结果 AAAAAAAAAAAAAAAAAA
题目名称 遥远的国度 最终得分 100
用户昵称 GravatarSky_miner 是否通过 通过
代码语言 C++ 运行时间 3.033 s
提交时间 2016-07-17 16:42:48 内存使用 15.05 MiB
显示代码纯文本
  1. #include <cstdio>
  2. #include <algorithm>
  3. using namespace std;
  4. const int maxn = 100000 + 10 ;
  5. const int inf = ~0U>>1;
  6. inline void read(int &x){
  7. x=0;char ch;bool flag = false;
  8. while(ch=getchar(),ch<'!');
  9. if( ch == '-' ) flag = true,ch=getchar();
  10. while(x=10*x+ch-'0',ch=getchar(),ch>'!');
  11. if( flag ) x=-x;
  12. }
  13. inline int cat_min(const int &a,const int &b){
  14. return a<b ? a:b;
  15. }
  16. inline int cat_max(const int &a,const int &b){
  17. return a>b ? a:b;
  18. }
  19. struct Edge{
  20. int to,next;
  21. }G[maxn<<1];
  22. int head[maxn],cnt;
  23. void add(int u,int v){
  24. G[++cnt].to = v;
  25. G[cnt].next = head[u];
  26. head[u] = cnt;
  27. }
  28. int n,m,root;
  29. int T[maxn<<2],cov[maxn<<2];
  30. int a[maxn],left[maxn],right[maxn],son[maxn];
  31. int deep[maxn],pos[maxn],fa[maxn][20],size[maxn],top[maxn],tim;
  32. #define v G[i].to
  33. inline void dfs1(int x){
  34. size[x]=1;son[x]=0;
  35. for(int i = head[x];i;i = G[i].next){
  36. if(v != fa[x][0]) {
  37. fa[v][0] = x;
  38. deep[v] = deep[x] + 1;
  39. dfs1(v);
  40. size[x] += size[v];
  41. if(size[v] > size[son[x]]) son[x] = v;
  42. }
  43. }
  44. }
  45. inline void dfs2(int x,int tp){
  46. left[x] = ++tim;
  47. top[x] = tp;
  48. pos[tim] = x;
  49. if(son[x]) dfs2(son[x],tp);
  50. for(int i = head[x];i;i = G[i].next)
  51. if(v != fa[x][0] && v != son[x]) dfs2(v,v);
  52. right[x] = tim;
  53. }
  54. #undef v
  55. inline void build(int rt,int l,int r){
  56. cov[rt] = -1;
  57. if(l == r){
  58. T[rt] = a[pos[l]];
  59. cov[rt] = -1;
  60. return;
  61. }
  62. int mid = l+r >> 1;
  63. build(rt<<1,l,mid);
  64. build(rt<<1|1,mid+1,r);
  65. T[rt] = cat_min(T[rt<<1],T[rt<<1|1]);
  66. }
  67. inline void pushdown(int rt){
  68. if(cov[rt] != -1){
  69. T[rt<<1] = T[rt<<1|1] = cov[rt<<1] = cov[rt<<1|1] = cov[rt];
  70. cov[rt] = -1;
  71. }
  72. }
  73. int Qx,Qy,ans;
  74. inline void change(int rt,int l,int r,int v){
  75. if(Qx <= l && r <= Qy){
  76. T[rt] = v;
  77. cov[rt] = v;
  78. return;
  79. }
  80. pushdown(rt);
  81. int mid = l+r >> 1;
  82. if(Qx <= mid) change(rt<<1,l,mid,v);
  83. if(Qy > mid) change(rt<<1|1,mid+1,r,v);
  84. T[rt] = cat_min(T[rt<<1],T[rt<<1|1]);
  85. }
  86. inline void query(int rt,int l,int r){
  87. if(Qx > Qy){
  88. ans = inf;
  89. return;
  90. }
  91. if(Qx <= l && r <= Qy){
  92. ans = cat_min(ans,T[rt]);
  93. return ;
  94. }
  95. pushdown(rt);
  96. int mid = l+r >> 1;
  97. if(Qx <= mid) query(rt<<1,l ,mid);
  98. if(Qy > mid) query(rt<<1|1,mid+1,r);
  99. T[rt] = cat_min(T[rt<<1],T[rt<<1|1]);
  100. }
  101. inline int query(int x,int y) {ans = inf;Qx = x;Qy = y;query(1,1,n); return ans;}
  102. inline void change(int x,int y,int v) {Qx = x; Qy = y; change(1,1,n,v);}
  103. inline void init(){
  104. for(int j = 1;j <= 19;++ j)
  105. for(int i = 1;i <= n;++ i)
  106. fa[i][j] = fa[fa[i][j-1]][j-1];
  107. }
  108. inline void fix(int x,int y,int v){
  109. int fx = top[x],fy = top[y];
  110. while(fx != fy) {
  111. if(deep[fx] < deep[fy]) {swap(x,y); swap(fx,fy);}
  112. change(left[fx],left[x],v);
  113. x = fa[fx][0]; fx = top[x];
  114. }
  115. if(deep[x] > deep[y]) swap(x,y);
  116. change(left[x],left[y],v);
  117. }
  118. int main(){
  119. freopen("bbbbb.in","r",stdin);
  120. freopen("bbbbb.out","w",stdout);
  121. read(n);read(m);
  122. int u,v,w;
  123. for(int i = 1;i < n;++ i){
  124. read(u);read(v);
  125. add(u,v); add(v,u);
  126. }
  127. for(int i = 1;i <= n;++i) read(a[i]);
  128. read(root);
  129. dfs1(root);
  130. dfs2(root,root);
  131. init();
  132. build(1,1,n);
  133. int op;
  134. while(m --){
  135. read(op);
  136. if(op == 1) read(u),root = u;
  137. else{
  138. if(op == 2){
  139. read(u); read(v); read(w);
  140. fix(u,v,w);
  141. }else{
  142. read(u);
  143. if(root == u) printf("%d\n",query(1,n));
  144. else{
  145. if(left[u] <= left[root] && right[root] <= right[u]){
  146. int y = root,d = deep[y] - deep[u] - 1;
  147. for(int i = 0;i <= 19;++i)
  148. if(d & (1 << i)) y=fa[y][i];
  149. printf("%d\n",cat_min(query(1,left[y]-1),query(right[y]+1,n)));
  150. }else printf("%d\n",query(left[u],right[u]));
  151. }
  152. }
  153. }
  154. }
  155. return 0;
  156. }