这题和 COT1 一定有 JQ 喵~

线段树的启发式合并,每次要连接两个点时就对比较小的那棵树暴力 DFS 一边

然后均摊时间依旧是 logn 的,均摊真是世界上最邪恶的东西了……

然后这题的数据是要卖萌么?!
testcase 的存在意义是被阿卡林噎掉了么?!

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <algorithm>
  4. const int sizeOfPoint=;
  5. const int sizeOfEdge=;
  6. const int sizeOfNode=;
  7.  
  8. inline int lg(int);
  9. inline void swap(int & , int & );
  10. inline char getch();
  11. inline int getint();
  12. inline void putint(int);
  13.  
  14. struct edge {int point; edge * next;};
  15. edge memory_edge[sizeOfEdge], * port_edge=memory_edge;
  16. inline edge * newedge(int, edge * );
  17. inline void link(int, int);
  18.  
  19. struct node {int c; node * l , * r; inline node();};
  20. node * null=new node();
  21. node memory_node[sizeOfNode], * port_node=memory_node;
  22. inline node * newnode(node * =null);
  23. node * insert(node * , int, int, int);
  24.  
  25. int b[sizeOfPoint], s[sizeOfPoint];
  26. int find(int);
  27. inline void merge(int, int);
  28.  
  29. int testcase;
  30. int N, M, T, U;
  31. int p[sizeOfPoint], q[sizeOfPoint];
  32. int f[sizeOfPoint], d[sizeOfPoint], a[][sizeOfPoint];
  33. edge * e[sizeOfPoint];
  34. node * t[sizeOfPoint];
  35. inline void clear();
  36. inline bool cmp(int, int);
  37. inline void discretization();
  38. void dfs(int);
  39. inline int lca(int, int);
  40. inline int query(int, int, int);
  41.  
  42. int main()
  43. {
  44. int lastans=;
  45.  
  46. testcase=getint();
  47. for (testcase=;testcase;testcase--)
  48. {
  49. N=getint(), M=getint(), T=getint();
  50. clear();
  51. for (int i=;i<=N;i++)
  52. p[i]=getint();
  53. for (int i=;i<=M;i++)
  54. {
  55. int u=getint(), v=getint();
  56. link(u, v);
  57. }
  58. discretization();
  59.  
  60. for (int i=;i<=N;i++) if (f[i]==-)
  61. {
  62. f[i]=; d[i]=;
  63. dfs(i);
  64. }
  65.  
  66. for (int i=;i<=T;i++)
  67. {
  68. char c=getch(); int x=getint()^lastans, y=getint()^lastans;
  69. if (c=='Q')
  70. {
  71. int k=getint()^lastans;
  72. lastans=query(x, y, k);
  73. putint(lastans);
  74. }
  75. else
  76. {
  77. int bx=find(x), by=find(y);
  78. if (bx==by) continue;
  79. if (s[bx]<s[by]) swap(x, y);
  80. link(x, y);
  81. f[y]=x; d[y]=d[x]+;
  82. dfs(y);
  83. }
  84. }
  85. }
  86.  
  87. return ;
  88. }
  89.  
  90. inline int lg(int x)
  91. {
  92. return -__builtin_clz(x);
  93. }
  94. inline void swap(int & x, int & y)
  95. {
  96. int z=x;
  97. x=y;
  98. y=z;
  99. }
  100. inline char getch()
  101. {
  102. register char ch;
  103. do ch=getchar(); while (ch!='L' && ch!='Q');
  104. return ch;
  105. }
  106. inline int getint()
  107. {
  108. register int num=;
  109. register char ch=, last;
  110. do last=ch, ch=getchar(); while (ch<'' || ch>'');
  111. do num=num*+ch-'', ch=getchar(); while (ch>='' && ch<='');
  112. if (last=='-') num=-num;
  113. return num;
  114. }
  115. inline void putint(int num)
  116. {
  117. char stack[];
  118. register int top=;
  119. if (num==) stack[top=]='';
  120. if (num<) putchar('-'), num=-num;
  121. for ( ;num;num/=) stack[++top]=num%+'';
  122. for ( ;top;top--) putchar(stack[top]);
  123. putchar('\n');
  124. }
  125.  
  126. inline edge * newedge(int point, edge * next)
  127. {
  128. edge * ret=port_edge++;
  129. ret->point=point; ret->next=next;
  130. return ret;
  131. }
  132. inline void link(int u, int v)
  133. {
  134. e[u]=newedge(v, e[u]);
  135. e[v]=newedge(u, e[v]);
  136. merge(u, v);
  137. }
  138.  
  139. inline node::node()
  140. {
  141. this->c=;
  142. this->l=this;
  143. this->r=this;
  144. }
  145. inline node * newnode(node * t)
  146. {
  147. node * newt=port_node++;
  148. *newt=*t;
  149. return newt;
  150. }
  151. node * insert(node * t, int l, int r, int k)
  152. {
  153. t=newnode(t);
  154. t->c++;
  155. if (l==r) return t;
  156.  
  157. int m=(l+r)>>;
  158. if (k<=m) t->l=insert(t->l, l, m, k);
  159. else t->r=insert(t->r, m+, r, k);
  160. return t;
  161. }
  162.  
  163. int find(int u)
  164. {
  165. return !b[u]?u:b[u]=find(b[u]);
  166. }
  167. inline void merge(int u, int v)
  168. {
  169. u=find(u); v=find(v);
  170. b[v]=u; s[u]+=s[v];
  171. }
  172.  
  173. inline void clear()
  174. {
  175. port_edge=memory_edge;
  176. memset(e, , sizeof(e));
  177. port_node=memory_node;
  178. for (int i=;i<=N;i++) t[i]=null;
  179. memset(f, -, sizeof(f));
  180. memset(d, -, sizeof(d));
  181. memset(b, , sizeof(b));
  182. memset(a, , sizeof(a));
  183. for (int i=;i<=N;i++) s[i]=;
  184. }
  185. inline bool cmp(int a, int b)
  186. {
  187. return p[a]<p[b];
  188. }
  189. inline void discretization()
  190. {
  191. static int k[sizeOfPoint];
  192.  
  193. for (int i=;i<=N;i++) k[i]=i;
  194. std::sort(k+, k+N+, cmp);
  195.  
  196. q[U=]=p[k[]]; p[k[]]=;
  197. for (int i=;i<=N;i++)
  198. {
  199. if (p[k[i]]>q[U]) q[++U]=p[k[i]];
  200. p[k[i]]=U;
  201. }
  202. }
  203. void dfs(int u)
  204. {
  205. t[u]=insert(t[f[u]], , U, p[u]);
  206. if (d[u]>)
  207. {
  208. int lim=lg(d[u]);
  209. a[][u]=f[u];
  210. for (int i=;i<=lim;i++)
  211. a[i][u]=a[i-][a[i-][u]];
  212. for (int i=lim+;i<;i++)
  213. a[i][u]=;
  214. }
  215.  
  216. for (edge * i=e[u];i;i=i->next) if (i->point!=f[u])
  217. {
  218. f[i->point]=u;
  219. d[i->point]=d[u]+;
  220. dfs(i->point);
  221. }
  222. }
  223. inline int lca(int u, int v)
  224. {
  225. if (d[u]<d[v]) swap(u, v);
  226. while (int dist=d[u]-d[v]) u=a[__builtin_ctz(dist)][u];
  227. if (u==v) return u;
  228. for (int i=;i>=;i--)
  229. if (a[i][u]!=a[i][v])
  230. u=a[i][u],
  231. v=a[i][v];
  232. return f[u];
  233. }
  234. inline int query(int a, int b, int k)
  235. {
  236. int c=lca(a, b), d=f[c];
  237. node * ta=t[a], * tb=t[b], * tc=t[c], * td=t[d];
  238. int l=, r=U, m;
  239.  
  240. for ( ;l<r; )
  241. {
  242. m=(l+r)>>;
  243. if (ta->l->c+tb->l->c-tc->l->c-td->l->c>=k)
  244. {
  245. ta=ta->l; tb=tb->l; tc=tc->l; td=td->l;
  246. r=m;
  247. }
  248. else
  249. {
  250. k-=ta->l->c+tb->l->c-tc->l->c-td->l->c;
  251. ta=ta->r; tb=tb->r; tc=tc->r; td=td->r;
  252. l=m+;
  253. }
  254. }
  255.  
  256. return q[l];
  257. }

又 R 又 T 一时爽

[BZOJ 3123]森林的更多相关文章

  1. BZOJ 3123 森林(函数式线段树)

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=3123 题意: 思路:总的来说,查询区间第K小利用函数式线段树的减法操作.对于两棵树的合并 ...

  2. BZOJ - 3123 森林 (可持久化线段树+启发式合并)

    题目链接 先把初始边建成一个森林,每棵树选一个根节点递归建可持久化线段树.当添加新边的时候,把结点数少的树暴力重构,以和它连边的那个点作为父节点继承线段树,并求出倍增数组.树的结点数可以用并查集来维护 ...

  3. [BZOJ 3123] [SDOI 2013]森林(可持久化线段树+并查集+启发式合并)

    [BZOJ 3123] [SDOI 2013]森林(可持久化线段树+启发式合并) 题面 给出一个n个节点m条边的森林,每个节点都有一个权值.有两种操作: Q x y k查询点x到点y路径上所有的权值中 ...

  4. 【sdoi2013】森林 BZOJ 3123

    Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数.第三行包含N个非负整数 ...

  5. BZOJ 3123: [Sdoi2013]森林 [主席树启发式合并]

    3123: [Sdoi2013]森林 题意:一个森林,加边,询问路径上k小值.保证任意时刻是森林 LCT没法搞,树上kth肯定要用树上主席树 加边?启发式合并就好了,小的树dfs重建一下 注意 测试点 ...

  6. bzoj 3123: [Sdoi2013]森林(45分暴力)

    3123: [Sdoi2013]森林 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 4184  Solved: 1235[Submit][Status ...

  7. AC日记——[Sdoi2013]森林 bzoj 3123

    3123: [Sdoi2013]森林 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 3216  Solved: 944[Submit][Status] ...

  8. Bzoj 3123: [Sdoi2013]森林(主席树+启发式合并)

    3123: [Sdoi2013]森林 Time Limit: 20 Sec Memory Limit: 512 MB Description Input 第一行包含一个正整数testcase,表示当前 ...

  9. ●BZOJ 3123 [Sdoi2013]森林

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=3123 题解: 主席树,在线,启发式合并 简单版(只有询问操作):[2588: Spoj 10 ...

随机推荐

  1. Oracle查询数据库中的所有表

    SELECT A.TABLE_NAME 表英文名,       A.TAB_COMMENTS 表中文名,       A.COLUMN_ID 序号,       A.COLUMN_NAME 英文名,  ...

  2. intellij idea 初步环境熟悉

    刚进来天渔项目组,连开发环境都是新的,学习至上 so 从eclipse过度过来还是有段时间的,期间虽然懵懂,但是也要坚持不耻下问 好了一下是idea的官网http://confluence.jetbr ...

  3. ThinkPHP(3)SQL查询语句

    ThinkPHP中对查询语句,包含了基本的查询方式.表达方式.快速查询.区间查询.组合查询.SQL查询.动态查询和子查询. 一.查询方式 ThinkPHP提供了三种基本的查询方式:字符串条件查询.索引 ...

  4. html页面3秒后自动跳转的方法有哪些

    在进行web前端开发实战练习时,我们常常遇到一种问题就是,web前端开发应该如何实现页面N秒之后自动跳转呢?通过查找相关html教程,总结了3个方法: 方法1: 最简单的一种:直接在前面<hea ...

  5. 使用USRP探索无线世界 Part 1:USRP从入门到追踪飞机飞行轨迹

    温馨提示:请自觉遵守无线电管理法规,依法设置和使用无线电设备 0×00 前言 USRP是数款流行的SDR硬件中功能和应用都相对成熟的一款产品,从WIFI协议.ZigBee协议.RFID协议.GSM通信 ...

  6. 【转】Duff's Device

    在看strcpy.memcpy等的实现发现用了内存对齐,每一个word拷贝一次的办法大大提高了实现效率,参加该blog(http://totoxian.iteye.com/blog/1220273). ...

  7. sudo apt-get install apache2 php7.0 php7.0-mysql mysql-server

    sudo apt-get install apache2 php7.0 php7.0-mysql mysql-server sudo apt-get install libapache2-mod-ph ...

  8. UE4 WCF RestFul 服务器 读取JSON 数据并解析 简单实例

    Note:不知道为什么通过Txt读取的JsonString,如果TXT 不是ANSI编码的话,会报JsonArrayStringToUStruct  Unable to parse. bool UWg ...

  9. 胡说REST(REpresentational State Transfer)

    Roy T. Fielding的2000年在他的博士论文中提出REpresentational State Transfer这一软件架构风格,相比"表述性状态转移"等等类似的拗口的 ...

  10. 如何让iOS 保持界面流畅?这些技巧你知道吗

    如何让iOS 保持界面流畅?这些技巧你知道吗   作者:ibireme这篇文章会非常详细的分析 iOS 界面构建中的各种性能问题以及对应的解决思路,同时给出一个开源的微博列表实现,通过实际的代码展示如 ...