带 加点 删边的块状树。

加点在 bzoj3720 说过。

删边其实就是块顶打标记,记录其属于哪棵树,防止在dfs搜集答案时跑到别的树上。

然后暴力把所在块拆开。

好像用邻接表存图,直接在vector里删边也行?

  1. #include<cstdio>
  2. #include<algorithm>
  3. #include<cmath>
  4. #include<vector>
  5. using namespace std;
  6. #define maxn 200001
  7. int Res,Num;char C,CH[];
  8. inline int Ge()
  9. {
  10. Res=;C='*';
  11. while(C<''||C>'')C=getchar();
  12. while(C>=''&&C<=''){Res=Res*+(C-'');C=getchar();}
  13. return Res;
  14. }
  15. inline void P(int x)
  16. {
  17. Num=;if(!x){putchar('');puts("");return;}
  18. while(x>)CH[++Num]=x%,x/=;
  19. while(Num)putchar(CH[Num--]+);
  20. putchar('\n');
  21. }
  22. typedef vector<int>::iterator ITER;
  23. vector<int>List[maxn],Goto[maxn];
  24. struct Graph
  25. {
  26. int v[maxn<<],first[maxn<<],next[maxn<<],en;
  27. void AddEdge(const int &a,const int &b)
  28. {v[++en]=b;next[en]=first[a];first[a]=en;}
  29. };
  30. Graph G,son;
  31. int top[maxn],siz[maxn],sz,w[maxn],belong_tree[maxn];
  32. bool vis[maxn],root[maxn];
  33. int n,x,y,m,op,tree_num;
  34. int ans,val,U;
  35. void makeblock(int cur)
  36. {
  37. vis[cur]=true;
  38. for(int i=G.first[cur];i;i=G.next[i])
  39. if(!vis[G.v[i]])
  40. {
  41. son.AddEdge(cur,G.v[i]);
  42. if(siz[top[cur]]<sz)
  43. {
  44. List[top[cur]].push_back(w[G.v[i]]);
  45. siz[top[cur]]++;
  46. top[G.v[i]]=top[cur];
  47. }
  48. makeblock(G.v[i]);
  49. }
  50. }
  51. void makeGoto(int cur)
  52. {
  53. for(int i=son.first[cur];i;i=son.next[i])
  54. {
  55. if(top[son.v[i]]!=top[cur])
  56. Goto[top[cur]].push_back(son.v[i]);
  57. makeGoto(son.v[i]);
  58. }
  59. }
  60. void dfs(int cur)//在Goto树上询问
  61. {
  62. ans+=( List[cur].end() - upper_bound( List[cur].begin() , List[cur].end() , val ) );
  63. for(ITER it=Goto[cur].begin();it!=Goto[cur].end();it++)
  64. if(belong_tree[*it]==belong_tree[cur])//通过标记控制在一棵树内
  65. dfs(*it);
  66. }
  67. void dfs_block(int cur)//在块内询问
  68. {
  69. if(w[cur]>val) ans++;
  70. for(int i=son.first[cur];i;i=son.next[i])
  71. if(top[son.v[i]]==top[cur]) dfs_block(son.v[i]);
  72. else if(belong_tree[son.v[i]]==belong_tree[top[cur]]) dfs(son.v[i]);
  73. }
  74. void query()
  75. {
  76. ans=;
  77. if(U==top[U]) dfs(U);
  78. else dfs_block(U);
  79. P(ans);
  80. }
  81. void update()
  82. {
  83. List[top[U]].erase( lower_bound(List[top[U]].begin(),List[top[U]].end(),w[U]) );
  84. w[U]=val;
  85. List[top[U]].insert( lower_bound(List[top[U]].begin(),List[top[U]].end(),val+) , val );
  86. }
  87. void AddPoint()
  88. {
  89. n++;
  90. if(siz[top[U]]<sz)
  91. {
  92. top[n]=top[U];
  93. siz[top[n]]++;
  94. }
  95. else
  96. {
  97. top[n]=n;
  98. siz[n]++;
  99. Goto[top[U]].push_back(n);
  100. belong_tree[n]=belong_tree[top[U]];
  101. }
  102. son.AddEdge(U,n);
  103. w[n]=val;
  104. List[top[n]].insert( lower_bound(List[top[n]].begin(),List[top[n]].end(),val+) , val );
  105. }
  106. void dfs_split(int cur)//设置每个块顶属于哪个树的标记
  107. {
  108. for(ITER it=Goto[cur].begin();it!=Goto[cur].end();it++)
  109. if(belong_tree[cur]==belong_tree[*it])
  110. dfs_split(*it);
  111. belong_tree[cur]=tree_num;
  112. }
  113. void dfs_split_block(int cur)//把分裂的块的下半部分重构块
  114. {
  115. List[U].push_back(w[cur]);
  116. for(int i=son.first[cur];i;i=son.next[i])
  117. {
  118. if(top[son.v[i]]==top[cur])
  119. dfs_split_block(son.v[i]);
  120. else if(belong_tree[son.v[i]]==belong_tree[top[U]])//顺手设置它下面的块的标记
  121. {
  122. Goto[U].push_back(son.v[i]);
  123. dfs_split(son.v[i]);
  124. }
  125. siz[U]++;
  126. }
  127. top[cur]=U;
  128. }
  129. void dfs_remain_block(int cur)//把分裂的块的上半部分重构块
  130. {
  131. List[top[U]].push_back(w[cur]); siz[top[U]]++;
  132. for(int i=son.first[cur];i;i=son.next[i])
  133. if( (!root[son.v[i]]) && (top[son.v[i]]==top[cur]) )
  134. dfs_remain_block(son.v[i]);
  135. }
  136. void Delete_Edge()
  137. {
  138. root[U]=true;
  139. tree_num++;
  140. if(U!=top[U])
  141. {
  142. List[top[U]].clear();siz[top[U]]=;
  143. dfs_remain_block(top[U]);
  144. sort(List[top[U]].begin(),List[top[U]].end());//重构分裂的块的上半部分
  145. dfs_split_block(U);
  146. belong_tree[U]=tree_num;
  147. sort(List[U].begin(),List[U].end());//重构分裂的块的下半部分
  148. }
  149. else
  150. dfs_split(U);
  151. }
  152. int main()
  153. {
  154. n=Ge();
  155. for(int i=;i<n;i++)
  156. {
  157. x=Ge();y=Ge();
  158. G.AddEdge(x,y);
  159. G.AddEdge(y,x);
  160. }
  161. sz=sqrt((double)n*log2(n));
  162. for(int i=;i<=n;i++)
  163. {
  164. w[i]=Ge();
  165. top[i]=i;
  166. siz[i]=;
  167. }
  168. makeblock();
  169. for(int i=;i<=n;i++)
  170. if(top[i]==i)
  171. {
  172. List[i].push_back(w[i]);
  173. sort(List[i].begin(),List[i].end());
  174. }
  175. makeGoto();
  176. root[]=true;
  177. m=Ge();
  178. for(int i=;i<=m;i++)
  179. {
  180. op=Ge();U=Ge();U^=ans;
  181. if(!op){val=Ge();val^=ans;query();}
  182. else if(op==){val=Ge();val^=ans;update();}
  183. else if(op==){val=Ge();val^=ans;AddPoint();}
  184. else Delete_Edge();
  185. }
  186. return ;
  187. }

【块状树】bzoj3731 Gty的超级妹子树的更多相关文章

  1. bzoj3731: Gty的超级妹子树

    一代神题啊orz(至少是以前年代的神题吧) 块状树 复杂度nsqrtnlogn 真是exciting 还没有卡时限 话不多说直接上代码 (最近解锁了记事本写代码的技能...感觉越来越依赖OJ调试了.. ...

  2. BZOJ 3731: Gty的超级妹子树

    3731: Gty的超级妹子树 Time Limit: 7 Sec  Memory Limit: 32 MBSubmit: 346  Solved: 96[Submit][Status][Discus ...

  3. bzoj3731: Gty的超级妹子树(树分块)

    传送门 分块树,代码参考了Manchery的 具体细节还是看代码好了 这题卡常……注意常数写好点…… //minamoto #include<iostream> #include<c ...

  4. bzoj Gty的超级妹子树 块状树

    Gty的超级妹子树 Time Limit: 7 Sec  Memory Limit: 32 MBSubmit: 500  Solved: 122[Submit][Status][Discuss] De ...

  5. 【块状树】bzoj3720 Gty的妹子树

    块状树.教程见:http://z55250825.blog.163.com/blog/static/1502308092014163413858/将树按一定大小分块,分成许多子树,在每个子树的根节点记 ...

  6. BZOJ3720 Gty的妹子树

    Description 我曾在弦歌之中听过你, 檀板声碎,半出折子戏. 舞榭歌台被风吹去, 岁月深处尚有余音一缕…… Gty神(xian)犇(chong)从来不缺妹子…… 他来到了一棵妹子树下,发现每 ...

  7. BZOJ 3720 gty的妹子树

    块状树裸题 块状树: 首先对树进行分块,分出的每一块都是一个连通块 通常的分块的方式如下: 1.父亲所在块不满,分到父亲所在块中 2.父亲所在块满,自己单独开一个块 (貌似有更为优越的分块方式? 注意 ...

  8. bzoj 3720: Gty的妹子树 块状树

    3720: Gty的妹子树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 412  Solved: 153[Submit][Status] Descr ...

  9. 【BZOJ3720】Gty的妹子树 块状树

    [BZOJ3720]Gty的妹子树 我曾在弦歌之中听过你,檀板声碎,半出折子戏.舞榭歌台被风吹去,岁月深处尚有余音一缕……Gty神(xian)犇(chong)从来不缺妹子……他来到了一棵妹子树下,发现 ...

随机推荐

  1. SQLMap的前世今生(Part1)

    http://www.freebuf.com/sectool/77948.html 一.前言 谈到SQL注入,第一时间就会想到神器SQLMAP,SQLMap是一款用来检测与利用的SQL注入开源工具.那 ...

  2. POJ 2398 Toy Storage 二分+叉积

    Description Mom and dad have a problem: their child, Reza, never puts his toys away when he is finis ...

  3. SLF4J 与Log4J

    为什么要使用SLF4J而不是Log4J 每一个Java程序员都知道日志对于任何一个Java应用程序,尤其是服务端程序是至关重要的,而很多程序员也已经熟悉各种不同的日志库如java.util.loggi ...

  4. vue-transition-fade

    <!Doctype> <html> <head> <meta charset="utf-8"> <meta name=&quo ...

  5. [Python]简单的外星人入侵游戏

    alien_invasion.py: import sys import pygame from setting import Settings from ship import Ship impor ...

  6. node搭建文件服务器

    python可以在目录下python -m http.server 8080来启动一个静态文件服务器,使用node实现一个 运行node fileServer.js D:\lanFeature 即可将 ...

  7. Spring--环境配置

    目录 1.1 Spring jar包下载 1.2 Hello World 参考资料 1.1 Spring jar包下载 (1)进入官网http://repo.spring.io(或者 http://m ...

  8. Android百度定位API的使用

    导入库文件 在下载页面下载最新的库文件.将liblocSDK2.4.so文件拷贝到libs/armeabi目录下.将locSDK2.4.jar文件拷贝到工程根目录下,并在工程属性->Java B ...

  9. TestRedis

    import org.junit.Before; import org.junit.Test; import redis.clients.jedis.Jedis; import java.util.H ...

  10. mongoDB文档操作【增删改】

    MongoDB 插入文档 文档的数据结构和JSON基本一样. 所有存储在集合中的数据都是BSON格式. BSON是一种类json的一种二进制形式的存储格式,简称Binary JSON. 插入文档 Mo ...