记录编号 548742 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [SYZOI Round1]滑稽♂树 最终得分 100
用户昵称 Gravatar瑆の時間~無盡輪迴·林蔭 是否通过 通过
代码语言 C++ 运行时间 15.913 s
提交时间 2020-01-30 18:30:32 内存使用 106.60 MiB
显示代码纯文本
  1. #include<iostream>
  2. #include<cstdio>
  3. #include<vector>
  4. #define R register
  5. #define LL inline
  6. using namespace std;
  7. struct PE
  8. {
  9. int v,ff,ch[2],size,cnt;
  10. };
  11. PE t[4800005];
  12. int root[120005],fa[30005],V[30005];
  13. vector<int> b[30005];
  14. int n,q,tot;
  15. int INF=2147483647;
  16. int read()
  17. {
  18. int x=0,ju=1;
  19. char c=getchar();
  20. while(c<'0'||c>'9')
  21. {
  22. if(c=='-')
  23. {
  24. ju=-1;
  25. }
  26. c=getchar();
  27. }
  28. while(c<='9'&&c>='0')
  29. {
  30. x=(x<<1)+(x<<3)+c-'0';
  31. c=getchar();
  32. }
  33. return x*ju;
  34. }
  35. LL void pushup(int x)
  36. {
  37. t[x].size=t[t[x].ch[0]].size+t[t[x].ch[1]].size+t[x].cnt;
  38. }
  39. LL void rotate(int x)
  40. {
  41. int y=t[x].ff;
  42. int z=t[y].ff;
  43. int k=(t[y].ch[1]==x);
  44. t[z].ch[t[z].ch[1]==y]=x;
  45. t[y].ch[k]=t[x].ch[k^1];
  46. t[t[x].ch[k^1]].ff=y;
  47. t[x].ch[k^1]=y;
  48. t[y].ff=x;
  49. t[x].ff=z;
  50. pushup(y);
  51. pushup(x);
  52. }
  53. LL void Splay(int x,int goal,int &root)
  54. {
  55. while(t[x].ff!=goal)
  56. {
  57. int y=t[x].ff;
  58. int z=t[y].ff;
  59. if(z!=goal)
  60. {
  61. (t[y].ch[1]==x)^(t[z].ch[1]==y)?rotate(x):rotate(y);
  62. }
  63. rotate(x);
  64. }
  65. if(goal==0)
  66. root=x;
  67. }
  68. LL void Insert(int x,int &root)
  69. {
  70. int u=root,ff;
  71. while(u&&t[u].v!=x)
  72. {
  73. ff=u;
  74. u=t[u].ch[t[u].v<x];
  75. }
  76. if(t[u].v==x)
  77. t[u].cnt++;
  78. else
  79. {
  80. u=++tot;
  81. t[u].v=x;
  82. t[u].ff=ff;
  83. if(ff)
  84. t[ff].ch[x>t[ff].v]=u;
  85. t[u].cnt=1;
  86. t[u].size=1;
  87. t[u].ch[0]=t[u].ch[1]=0;
  88. }
  89. Splay(u,0,root);
  90. }
  91. LL void Find(int x,int &root)
  92. {
  93. int u=root;
  94. while(t[u].ch[x>t[u].v]&&t[u].v!=x)
  95. {
  96. u=t[u].ch[x>t[u].v];
  97. }
  98. Splay(u,0,root);
  99. }
  100. LL int Rank(int x,int &root)
  101. {
  102. Find(x,root);
  103. if(x<=t[root].v)
  104. return t[t[root].ch[0]].size+1;
  105. if(x>t[root].v)
  106. return t[t[root].ch[0]].size+t[root].cnt+1;
  107. }
  108. LL int KTH(int x,int &root)
  109. {
  110. int u=root;
  111. if(t[u].size<x)
  112. return -2147483647;
  113. while(1)
  114. {
  115. int y=t[u].ch[0];
  116. if(t[y].size+t[u].cnt<x)
  117. {
  118. x-=t[y].size+t[u].cnt;
  119. u=t[u].ch[1];
  120. }
  121. else
  122. {
  123. if(t[y].size>=x)
  124. u=t[u].ch[0];
  125. else
  126. return t[u].v;
  127. }
  128. }
  129. }
  130. LL int Next(int x,int f,int &root)
  131. {
  132. Find(x,root);
  133. int u=root;
  134. if(t[u].v>x&&f)
  135. return u;
  136. if(t[u].v<x&&!f)
  137. return u;
  138. u=t[u].ch[f];
  139. while(t[u].ch[f^1])
  140. u=t[u].ch[f^1];
  141. return u;
  142. }
  143. LL void Delete(int x,int &root)
  144. {
  145. int last=Next(x,0,root);
  146. int ext=Next(x,1,root);
  147. Splay(last,0,root);
  148. Splay(ext,last,root);
  149. int del=t[ext].ch[0];
  150. if(t[del].cnt>1)
  151. {
  152. t[del].cnt--;
  153. Splay(del,0,root);
  154. }
  155. else
  156. t[ext].ch[0]=0;
  157. }
  158. LL void DFS(int x,int f)
  159. {
  160. root[x]=++tot;
  161. Insert(INF,root[x]);
  162. Insert(-INF,root[x]);
  163. fa[x]=f;
  164. for(int i=0;i<b[x].size();i++)
  165. {
  166. int to=b[x][i];
  167. if(to==f)
  168. continue;
  169. DFS(to,x);
  170. }
  171. }
  172. LL void ADD()
  173. {
  174. for(R int i=1;i<=n;i++)
  175. {
  176. R int u=i;
  177. while(1)
  178. {
  179. if(u==1)
  180. {
  181. Insert(V[i],root[u]);
  182. break;
  183. }
  184. else
  185. {
  186. Insert(V[i],root[u]);
  187. u=fa[u];
  188. }
  189. }
  190. }
  191. }
  192. LL int Check(int u,int k)
  193. {
  194. return KTH(k,root[u]);
  195. }
  196. LL int Query(int u,int a,int b)
  197. {
  198. return Rank(b+1,root[u])-Rank(a,root[u]);
  199. }
  200. LL void Change(int u,int x)
  201. {
  202. R int ts=u;
  203. while(1)
  204. {
  205. Delete(V[u],root[ts]);
  206. Insert(x,root[ts]);
  207. if(ts==1)
  208. break;
  209. else
  210. ts=fa[ts];
  211. }
  212. V[u]=x;
  213. }
  214. int LINYIN()
  215. {
  216. freopen("hjtree.in","r",stdin);
  217. freopen("hjtree.out","w",stdout);
  218. n=read();
  219. for(int i=1;i<=n;i++)
  220. {
  221. V[i]=read();
  222. //scanf("%d",&V[i]);
  223. }
  224. int a1,a2,a3,a4;
  225. for(int i=1;i<n;i++)
  226. {
  227. a1=read();
  228. a2=read();
  229. b[a1].push_back(a2);
  230. b[a2].push_back(a1);
  231. }
  232. DFS(1,0);
  233. ADD();
  234. q=read();
  235. //scanf("%d",&q);
  236. for(int i=1;i<=q;i++)
  237. {
  238. a1=read();
  239. a2=read();
  240. a3=read();
  241. //scanf("%d%d%d",&a1,&a2,&a3);
  242. if(a1==1)
  243. {
  244. printf("%d\n",Check(a2,a3+1));
  245. }
  246. if(a1==2)
  247. {
  248. a4=read();
  249. //scanf("%d",&a4);
  250. printf("%d\n",Query(a2,a3,a4));
  251. }
  252. if(a1==3)
  253. {
  254. Change(a2,a3);
  255. }
  256. }
  257. return 0;
  258. }
  259. int sed=LINYIN();
  260. int main()
  261. {
  262. ;
  263. }