Box

\[Time Limit: 5000 ms \quad Memory Limit: 32768 kB
\]

题意

给出 \(n\) 个箱子的包含关系,每次两种操作。

操作 \(1\):把 \(x\) 的箱子及里面的箱子一块挪到 \(y\) 箱子里面去。

操作 \(2\):查询 \(x\) 箱子的最外层的箱子编号。

思路

对于每一大块箱子,可以看成树和子树的包含关系,那么可以根据树的 \(dfs\) 序,把一个箱子所包含的箱子拍成一个区间,这样就变成了很多颗树。为了方便后面的操作,对于每个箱子 \(x\) 所包含的区间,用标号 \(x\) 来表示开始的位置,\(x+n\) 来表示结束的位置。

使用 \(splay\) 维护每多颗树的 \(dfs\) 序。由于每棵树都有一个自己的 \(root\) 节点,我们让他们的 \(root\) 节点统一连向 \(0\) 这个虚点。

再来看一看操作,操作 \(1\) 可以变成删除操作以及区间移动操作。操作 \(2\) 就是普通的查询操作。

对于操作 \(1\),先找到 \(x\) 和 \(x+n\) 所在的位置,把 \(x\) \(splay\) 到其树的 \(root\) 上,把 \(x+n\) \(slay\) 到 \(x\) 的右子树上,那么我们要转移的树就是 \(x->x+n->x+n\)的所有左子树。 同样的,要查找非法条件,只要看 \(y\) 在不在这棵树里面就可以了。

最后只要把这棵树插到标号 \(y\) 的右边就可以了。可以先把 \(y\) \(splay\) 到其 \(root\) 上,然后找到 \(y\) 下标意义上的后继,然后插入就行了。

对于操作\(2\),只要把 \(x\) \(splay\) 到其树的 \(root\) 上,然后查询这棵树里面的最小标号是多少,也就找到了最外的箱子的标号。

  1. /***************************************************************
  2. > File Name : a.cpp
  3. > Author : Jiaaaaaaaqi
  4. > Created Time : Mon 14 Oct 2019 07:20:55 PM CST
  5. ***************************************************************/
  6. #include <map>
  7. #include <set>
  8. #include <list>
  9. #include <ctime>
  10. #include <cmath>
  11. #include <stack>
  12. #include <queue>
  13. #include <cfloat>
  14. #include <string>
  15. #include <vector>
  16. #include <cstdio>
  17. #include <bitset>
  18. #include <cstdlib>
  19. #include <cstring>
  20. #include <iostream>
  21. #include <algorithm>
  22. #define lowbit(x) x & (-x)
  23. #define mes(a, b) memset(a, b, sizeof a)
  24. #define fi first
  25. #define se second
  26. #define pb push_back
  27. #define pii pair<int, int>
  28. typedef unsigned long long int ull;
  29. typedef long long int ll;
  30. const int maxn = 1e5 + 10;
  31. const int maxm = 1e5 + 10;
  32. const ll mod = 1e9 + 7;
  33. const ll INF = 1e18 + 100;
  34. const int inf = 0x3f3f3f3f;
  35. const double pi = acos(-1.0);
  36. const double eps = 1e-8;
  37. using namespace std;
  38. int n, m;
  39. int cas, tol, T;
  40. vector<int> vv[maxn];
  41. int root, tot;
  42. int ch[maxn][2];
  43. int sz[maxn], fa[maxn], val[maxn], cnt[maxn];
  44. int a[maxn], id[maxn];
  45. void init() {
  46. tol = root = tot = 0;
  47. for(int i=0; i<=n; i++) {
  48. vv[i].clear();
  49. }
  50. }
  51. int newnode(int x, int f) {
  52. mes(ch[++tot], 0);
  53. val[tot] = x;
  54. id[x] = tot;
  55. fa[tot] = f;
  56. sz[tot] = cnt[tot] = 1;
  57. return tot;
  58. }
  59. void pushdown(int x) { }
  60. void pushup(int x) {
  61. if(x) {
  62. sz[x] = cnt[x];
  63. if(ch[x][0]) sz[x] += sz[ch[x][0]];
  64. if(ch[x][1]) sz[x] += sz[ch[x][1]];
  65. }
  66. }
  67. int get(int x) {
  68. return ch[fa[x]][1] == x;
  69. }
  70. void rotate(int x) {
  71. int f = fa[x], gf = fa[f], k = get(x), w = ch[x][k ^ 1];
  72. pushdown(f), pushdown(x);
  73. ch[f][k] = w, fa[w] = f;
  74. ch[gf][get(f)] = x, fa[x] = gf;
  75. ch[x][k ^ 1] = f, fa[f] = x;
  76. pushup(f), pushup(x);
  77. }
  78. void splay(int x, int goal = 0) {
  79. int f, gf;
  80. while (fa[x] != goal) {
  81. f = fa[x], gf = fa[f];
  82. pushdown(gf), pushdown(f), pushdown(x);
  83. if (gf != goal) {
  84. if(get(x) == get(f)) rotate(f);
  85. else rotate(x);
  86. }
  87. rotate(x);
  88. }
  89. if (!goal) root = x;
  90. }
  91. int build(int l, int r, int f) {
  92. if(l > r) return 0;
  93. int mid = l+r>>1;
  94. int now = newnode(a[mid], f);
  95. ch[now][0] = build(l, mid-1, now);
  96. ch[now][1] = build(mid+1, r, now);
  97. pushup(now);
  98. return now;
  99. }
  100. void dfs(int u) {
  101. a[tol++] = u;
  102. for(auto v : vv[u]) {
  103. dfs(v);
  104. }
  105. a[tol++] = u+n;
  106. }
  107. void Move(int a, int b) {
  108. if(a == b) return ;
  109. int x = id[a], y = id[a+n], z = id[b];
  110. splay(x), splay(y, x);
  111. while(z && z!=y) {
  112. if(ch[y][0] == z) return ;
  113. z = fa[z];
  114. }
  115. if(ch[x][0]==0 || ch[y][1]==0) {
  116. fa[ch[x][0]+ch[y][1]] = 0;
  117. } else {
  118. int k = ch[y][1];
  119. while(ch[k][0]) k = ch[k][0];
  120. splay(k, y);
  121. int cur = ch[y][1];
  122. ch[cur][0] = ch[x][0];
  123. fa[ch[x][0]] = cur;
  124. fa[cur] = 0;
  125. pushup(cur);
  126. }
  127. ch[x][0] = ch[y][1] = 0;
  128. if(b == 0) return ;
  129. z = id[b];
  130. splay(z);
  131. if(ch[z][1]) {
  132. z = ch[z][1];
  133. while(ch[z][0]) z = ch[z][0];
  134. }
  135. ch[z][0] = x;
  136. fa[x] = z;
  137. pushup(z);
  138. }
  139. void Query(int x) {
  140. x = id[x];
  141. splay(x);
  142. while(ch[x][0]) x = ch[x][0];
  143. printf("%d\n", val[x]);
  144. }
  145. int main() {
  146. // freopen("in", "r", stdin);
  147. int flag = 0;
  148. while(~scanf("%d", &n)) {
  149. if(flag) printf("\n");
  150. flag = 1;
  151. init();
  152. for(int i=1; i<=n; i++) {
  153. int x;
  154. scanf("%d", &x);
  155. vv[x].pb(i);
  156. }
  157. dfs(0);
  158. tol--;
  159. // for(int i=1; i<tol; i++) printf("%d%c", a[i], i==tol-1 ? '\n':' ');
  160. int st = 1, c = 0;
  161. for(int i=1; i<tol; i++) {
  162. if(a[i] <= n) c++;
  163. else c--;
  164. if(c == 0) {
  165. build(st, i, 0);
  166. st = i+1;
  167. }
  168. }
  169. // for(int i=1; i<=tot; i++) printf("val[%d] = %d\n", i, val[i]);
  170. scanf("%d", &m);
  171. char s[10];
  172. while(m--) {
  173. int x, y;
  174. scanf("%s", s+1);
  175. if(s[1] == 'M') {
  176. scanf("%d%d", &x, &y);
  177. Move(x, y);
  178. } else {
  179. scanf("%d", &x);
  180. Query(x);
  181. }
  182. }
  183. }
  184. }

Box HDU - 2475 (Splay 维护森林)的更多相关文章

  1. HDU - 2475:Box(splay维护森林)

    There are N boxes on the ground, which are labeled by numbers from 1 to N. The boxes are magical, th ...

  2. hdu 2475 BOX (splay)

    版权声明:本文为博主原创文章,未经博主允许不得转载. hdu 2475 Splay树是一种神奇的东西... 题意: 有一些箱子,要么放在地上,要么放在某个箱子里面 . 现在有两种操作: (1) MOV ...

  3. HDU 2475 BOX 动态树 Link-Cut Tree

    Box Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) [Problem De ...

  4. hdu 3436 splay树+离散化*

    Queue-jumpers Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) To ...

  5. hdu 4453 splay

    Looploop Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total S ...

  6. 【BZOJ 3729】3729: Gty的游戏 (Splay维护dfs序+博弈)

    未经博主同意不得转载 3729: Gty的游戏 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 448  Solved: 150 Description ...

  7. HNOI2004宠物收养所(splay维护二叉搜索树模板题)

    描述 最近,阿Q开了一间宠物收养所.收养所提供两种服务:收养被主人遗弃的宠物和让新的主人领养这些宠物.每个领养者都希望领养到自己满意的宠物,阿Q根据领养者的要求通过他自己发明的一个特殊的公式,得出该领 ...

  8. BZOJ 3729 splay维护DFS序+博弈论

    思路: 这像是 阶梯Nim之类的东西 我们 直接把sg函数 设成mod(L+1)的 一棵子树 向下的奇数层上的石子xor起来 就是答案 有加点和改值的操作 就splay维护一下 //By Sirius ...

  9. BZOJ 1492 [NOI2007]货币兑换Cash (CDQ分治/splay 维护凸包)

    题目大意:太长了略 splay调了两天一直WA弃疗了 首先,我们可以猜一个贪心,如果买/卖,就一定都买/卖掉,否则不买/卖 反正货币的行情都是已知的,没有任何风险,所以肯定要选择最最最优的方案了 容易 ...

随机推荐

  1. Tomcat启用HTTPS协议配置过程

    Article1较为简洁,Article2较为详细,测试可行. Article1 概念简介 Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器,在中小型系统和并发访问 ...

  2. APP 链接ROS时出现pymongo.errors.ServerSelectionTimeoutError: localhost:27017 错误

    ROS版本上kinetic ,APP是官网开源的make a map,当app链接ROS进行建图时,会出现报错:pymongo.errors.ServerSelectionTimeoutError: ...

  3. Github的初始设置

    设置姓名和邮箱地址 git config --global user.name "Firstname Lastname" git config --global user.emai ...

  4. centos上安装grafana

    wget https://dl.grafana.com/oss/release/grafana-6.2.5-1.x86_64.rpm yum localinstall grafana-6.2.5-1. ...

  5. 【MySQL】binlog2sql

    binlog2sql 1.安装 shell> git clone https://github.com/danfengcao/binlog2sql.git && cd binlo ...

  6. 算法设计与分析(李春保)练习题答案v2

    ----------------------------------------------------- Page 1 --------------------------------------- ...

  7. Windows 10 更新补丁后Visual Studio 2017 运行项目出现错误

    问题: 今天更新了Windows 10(版本 1709)推送最新补丁后,打开Visual Studio 2017运行Web项目,都出现“指定的参数超出有效值的范围 参数名:site”,如下图: 解决方 ...

  8. mysql 实现row_number功能

    需求: 解答:由于mysql 中没有类似oracle中的 row_number功能,要实现row_number 可以使用如下功能: Select pkid,(@row_number:=@row_num ...

  9. 初始认知学习 .net core 逐步加深

    1.一般用空项目练手 2.一般你已经有数据库的情况下使用如下的方式 开始生成类的操作 这里我使用的是Database First模式,使用工具Scaffold-DbContext(数据库上下文脚手架) ...

  10. ASP.NET MVC EF 连接数据库(二)-----Model First

    Model first (VS2015 ,Sql Server2014) 新建MVC项目     右键product ,新增标量属性(数据库表中的字段)   Ctrl + S 保存页面,右键“根据模型 ...