记录编号 444162 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [SYZOI Round1]滑稽♂树 最终得分 100
用户昵称 Gravatarwumingshi 是否通过 通过
代码语言 C++ 运行时间 2.935 s
提交时间 2017-09-02 11:04:16 内存使用 44.54 MiB
显示代码纯文本
  1. #include<cstdio>
  2. const int N=2e5+10;
  3. struct node
  4. {
  5. int num,size,cnt;
  6. node *ch[2],*fa;
  7. inline int getwh(){return fa->ch[0]==this?0:1;}
  8. inline void update(){size=ch[0]->size+ch[1]->size+cnt;}
  9. inline void setch(int wh,node *child);
  10. }pool[1500000],*t[N<<2],*null;
  11. inline void node::setch(int wh,node *child)
  12. {
  13. ch[wh]=child;
  14. if(child!=null) child->fa=this;
  15. update();
  16. }
  17. struct edge
  18. {
  19. int nxt,to;
  20. }e[N<<1];
  21. int head[N],a[N],size[N],pos[N],s[N];
  22. int n,m,opt,x,y,z,tot,cnt,num;
  23. inline void add(int x,int y)
  24. {
  25. e[++num].nxt=head[x],e[num].to=y,head[x]=num;
  26. e[++num].nxt=head[y],e[num].to=x,head[y]=num;
  27. }
  28. void dfs(int now,int fa)
  29. {
  30. size[now]=1,pos[now]=++cnt;s[cnt]=a[now];
  31. for(int i=head[now];i;i=e[i].nxt)
  32. if(e[i].to!=fa) dfs(e[i].to,now),size[now]+=size[e[i].to];
  33. }
  34. inline node *getnew(int value,bool normal)
  35. {
  36. node *now=pool+ ++tot;
  37. now->ch[0]=now->ch[1]=now->fa=null;
  38. if(normal) now->size=now->cnt=1;
  39. now->num=value;
  40. return now;
  41. }
  42. inline void rotate(node *now)
  43. {
  44. node *fa=now->fa,*grand=fa->fa;
  45. int wh=now->getwh();
  46. fa->setch(wh,now->ch[wh^1]);
  47. now->setch(wh^1,fa);
  48. now->fa=grand;
  49. if(grand!=null) grand->ch[grand->ch[0]==fa?0:1]=now;
  50. fa->update(),now->update(),grand->update();
  51. }
  52. inline void splay(node *now,node *tar,node *&root)
  53. {
  54. for(;now->fa!=tar;rotate(now))
  55. if(now->fa->fa!=tar) now->getwh()==now->fa->getwh()?rotate(now->fa):rotate(now);
  56. if(tar==null) root=now;
  57. }
  58. inline void insert(int value,node *&root,bool normal)
  59. {
  60. node *now=root,*last=null;
  61. while(now!=null)
  62. {
  63. last=now;
  64. if(now->num==value){now->cnt++,now->size++,splay(now,null,root);return;}
  65. if(now->num>value) now=now->ch[0];
  66. else now=now->ch[1];
  67. }
  68. if(last==null){root=getnew(value,normal);return;}
  69. now=getnew(value,normal);
  70. if(last->num>value) last->setch(0,now);
  71. else last->setch(1,now);
  72. splay(now,null,root);
  73. }
  74. inline node *find(int value,node *&root)
  75. {
  76. node *now=root;
  77. while(now!=null)
  78. {
  79. if(now->num==value){splay(now,null,root);return now;}
  80. if(now->num>value) now=now->ch[0];
  81. else now=now->ch[1];
  82. }
  83. }
  84. inline void del(int value,node *&root)
  85. {
  86. node *now=find(value,root);
  87. if(now->cnt>1){now->cnt--,now->size--,splay(now,null,root);return;}
  88. if(now->ch[0]==null&&now->ch[1]==null){root=null;return;}
  89. if(now->ch[0]==null){root=now->ch[1],root->fa=null;return;}
  90. if(now->ch[1]==null){root=now->ch[0],root->fa=null;return;}
  91. node *Root=now->ch[0];
  92. while(Root->ch[1]!=null) Root=Root->ch[1];
  93. splay(Root,now,root);
  94. Root->setch(1,now->ch[1]);
  95. Root->fa=null;
  96. root=Root;
  97. }
  98. inline int rank(int value,node *&root)
  99. {
  100. int ans=0;node *now=root;
  101. while(now!=null)
  102. {
  103. if(now->num==value){ans+=now->ch[0]->size;splay(now,null,root);return ans;}
  104. if(now->num>value) now=now->ch[0];
  105. else ans+=now->ch[0]->size+now->cnt,now=now->ch[1];
  106. }
  107. return ans;
  108. }
  109. inline node *pre(int value,node *&root)
  110. {
  111. node *now=root,*ans=null;
  112. while(now!=null)
  113. if(now->num<value) ans=now,now=now->ch[1];
  114. else now=now->ch[0];
  115. return ans;
  116. }
  117. inline node *nxt(int value,node *&root)
  118. {
  119. node *now=root,*ans=null;
  120. while(now!=null)
  121. if(now->num>value) ans=now,now=now->ch[0];
  122. else now=now->ch[1];
  123. return ans;
  124. }
  125. inline int ask(int l,int r,node *&root)
  126. {
  127. splay(pre(l,root),null,root);
  128. splay(nxt(r,root),root,root);
  129. return root->ch[1]->ch[0]->size;
  130. }
  131. inline void init(int l,int r,node *&root)
  132. {
  133. root=null;
  134. insert(-1,root,0),insert(20000,root,0);
  135. for(int i=l;i<=r;i++)
  136. insert(s[i],root,1);
  137. }
  138. void build(int l,int r,int now)
  139. {
  140. init(l,r,t[now]);
  141. if(l==r) return;
  142. int mid=(l+r)>>1;
  143. build(l,mid,now<<1);
  144. build(mid+1,r,now<<1|1);
  145. }
  146. void change(int p,int l,int r,int now,int num)
  147. {
  148. del(s[p],t[now]),insert(num,t[now],1);
  149. if(l==r) return;
  150. int mid=(l+r)>>1;
  151. if(p<=mid) change(p,l,mid,now<<1,num);
  152. else change(p,mid+1,r,now<<1|1,num);
  153. }
  154. int askrank(int L,int R,int l,int r,int now,int num)
  155. {
  156. if(L<=l&&r<=R) return rank(num,t[now]);
  157. int mid=(l+r)>>1,ans=0;
  158. if(L<=mid) ans=askrank(L,R,l,mid,now<<1,num);
  159. if(R>mid) ans+=askrank(L,R,mid+1,r,now<<1|1,num);
  160. return ans;
  161. }
  162. inline int Rank(int l,int r,int num)
  163. {
  164. int L=0,R=10001;
  165. while(L<R)
  166. {
  167. int mid=(L+R)>>1;
  168. if(askrank(l,r,1,n,1,mid)<num) L=mid+1;
  169. else R=mid;
  170. }
  171. return L-1;
  172. }
  173. inline int askval(int L,int R,int l,int r,int now,int x,int y)
  174. {
  175. if(L<=l&&r<=R) return ask(x,y,t[now]);
  176. int mid=(l+r)>>1,ans=0;
  177. if(L<=mid) ans=askval(L,R,l,mid,now<<1,x,y);
  178. if(R>mid) ans+=askval(L,R,mid+1,r,now<<1|1,x,y);
  179. return ans;
  180. }
  181. int main()
  182. {
  183. freopen("hjtree.in","r",stdin);
  184. freopen("hjtree.out","w",stdout);
  185. null=pool;
  186. null->ch[0]=null->ch[1]=null;
  187. scanf("%d",&n);
  188. for(int i=1;i<=n;i++)
  189. scanf("%d",&a[i]);
  190. for(int i=1;i<n;i++)
  191. scanf("%d%d",&x,&y),add(x,y);
  192. dfs(1,0);build(1,n,1);
  193. scanf("%d",&m);int tmp=0;
  194. while(m--)
  195. {
  196. tmp++;
  197. scanf("%d%d%d",&opt,&x,&y);
  198. if(opt==1) printf("%d\n",Rank(pos[x],pos[x]+size[x]-1,y));
  199. else if(opt==2) scanf("%d",&z),printf("%d\n",askval(pos[x],pos[x]+size[x]-1,1,n,1,y,z));
  200. else change(pos[x],1,n,1,y),s[pos[x]]=y;
  201. }
  202. return 0;
  203. }