传送门

1.并查集骗分(数据太水,比正解还快。。。)

我们知道,并查集有一步操作叫“路径压缩”,但是本题的并查集我们不能路径压缩,否则就无法进行Destroy操作。那每一步操作我们应该怎么做呢?

对于Connect x y操作,先把x变成集合的根,之后root[x] = y;

对于Destroy x y操作,先把x变成集合的根,此时root[y]必然为x,令root[y] = y即可。

对于Query x y操作,看看x和y所在集合的根是不是一样的就好了。

那么如何把x变成集合的根呢?只要把从x到根路径上的每一条边反向即可,所以不能进行路径压缩。

其实并查集的解法也有用 lct 的思想的。

在这里,并查集中的两点之间的边就表示连接两个洞穴之间的边,非常的直接。。

注意一个细节 : 题目中说——无论通道怎么改变,任意时刻任意两个洞穴之间至多只有一条路径

也就是说不会有环!这也正是能用并查集做的原因之一。

——代码

  1. #include <cstdio>
  2. #include <iostream>
  3. #define N 10001
  4.  
  5. int n, m;
  6. int f[N];
  7.  
  8. inline int read()
  9. {
  10. int x = , f = ;
  11. char ch = getchar();
  12. for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -;
  13. for(; isdigit(ch); ch = getchar()) x = (x << ) + (x << ) + ch - '';
  14. return x * f;
  15. }
  16.  
  17. inline int find(int x)
  18. {
  19. while(x ^ f[x]) x = f[x];
  20. return x;
  21. }
  22.  
  23. inline void make_root(int x, int c)
  24. {
  25. if(x ^ f[x]) make_root(f[x], x);
  26. f[x] = c;
  27. }
  28.  
  29. int main()
  30. {
  31. int i, j, x, y, fx, fy;
  32. char s[];
  33. n = read();
  34. m = read();
  35. for(i = ; i <= n; i++) f[i] = i;
  36. for(i = ; i <= m; i++)
  37. {
  38. scanf("%s", s);
  39. x = read();
  40. y = read();
  41. if(s[] == 'Q') find(x) == find(y) ? puts("Yes") : puts("No");
  42. else if(s[] == 'C') make_root(x, x), f[x] = y;
  43. else make_root(x, x), f[y] = y;
  44. }
  45. return ;
  46. }

2.lct(正解)

就是模板啦

——代码

  1. #include <cstdio>
  2. #include <iostream>
  3. #define N 10001
  4. #define swap(x, y) ((x) ^= (y) ^= (x) ^= (y))
  5.  
  6. int n, m;
  7. int f[N], rev[N], son[N][], s[N], size[N];
  8.  
  9. inline int read()
  10. {
  11. int x = , f = ;
  12. char ch = getchar();
  13. for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -;
  14. for(; isdigit(ch); ch = getchar()) x = (x << ) + (x << ) + ch - '';
  15. return x * f;
  16. }
  17.  
  18. inline bool isroot(int x)
  19. {
  20. return son[f[x]][] ^ x && son[f[x]][] ^ x;
  21. }
  22.  
  23. inline int get(int x)
  24. {
  25. return son[f[x]][] == x;
  26. }
  27.  
  28. inline void pushdown(int x)
  29. {
  30. if(x && rev[x])
  31. {
  32. swap(son[x][], son[x][]);
  33. if(son[x][]) rev[son[x][]] ^= ;
  34. if(son[x][]) rev[son[x][]] ^= ;
  35. rev[x] = ;
  36. }
  37. }
  38.  
  39. inline void rotate(int x)
  40. {
  41. int old = f[x], oldf = f[old], wh = get(x);
  42.  
  43. if(!isroot(old))
  44. son[oldf][son[oldf][] == old] = x;
  45. f[x] = oldf;
  46.  
  47. son[old][wh] = son[x][wh ^ ];
  48. f[son[old][wh]] = old;
  49.  
  50. son[x][wh ^ ] = old;
  51. f[old] = x;
  52. }
  53.  
  54. inline void splay(int x)
  55. {
  56. int i, fa, t = ;
  57. s[++t] = x;
  58. for(i = x; !isroot(i); i = f[i]) s[++t] = f[i];
  59. for(i = t; i >= ; i--) pushdown(s[i]);
  60. for(; !isroot(x); rotate(x))
  61. if(!isroot(fa = f[x]))
  62. rotate(get(x) == get(fa) ? fa : x);
  63. }
  64.  
  65. inline void access(int x)
  66. {
  67. for(int t = ; x; t = x, x = f[x]) splay(x), son[x][] = t;
  68. }
  69.  
  70. inline void reverse(int x)
  71. {
  72. access(x);
  73. splay(x);
  74. rev[x] ^= ;
  75. }
  76.  
  77. inline int find(int x)
  78. {
  79. access(x);
  80. splay(x);
  81. while(son[x][]) x = son[x][];
  82. return x;
  83. }
  84.  
  85. inline void link(int x, int y)
  86. {
  87. reverse(x);
  88. f[x] = y;
  89. splay(x);
  90. }
  91.  
  92. inline void cut(int x, int y)
  93. {
  94. reverse(x);
  95. access(y);
  96. splay(y);
  97. son[y][] = f[x] = ;
  98. }
  99.  
  100. int main()
  101. {
  102. int i, j, x, y;
  103. char s[];
  104. n = read();
  105. m = read();
  106. for(i = ; i <= m; i++)
  107. {
  108. scanf("%s", s);
  109. x = read();
  110. y = read();
  111. if(s[] == 'Q') find(x) == find(y) ? puts("Yes") : puts("No");
  112. if(s[] == 'C') link(x, y);
  113. if(s[] == 'D') cut(x, y);
  114. }
  115. return ;
  116. }

[luoguP2147] [SDOI2008]Cave 洞穴勘测(并查集 || lct)的更多相关文章

  1. 【bzoj2049】[Sdoi2008]Cave 洞穴勘测——线段树上bfs求可撤销并查集

    题面 2049: [Sdoi2008]Cave 洞穴勘测 Time Limit: 10 Sec Memory Limit: 259 MB Submit: 12030 Solved: 6024 Desc ...

  2. 【bzoj2049】[Sdoi2008]Cave 洞穴勘测 link-cut-tree

    2016-05-30  11:04:51 学习了link-cut-tree 二中神犇封禹的讲义感觉讲的超级清晰易懂啊(没有的可以q窝 算是模板吧 #include<bits/stdc++.h&g ...

  3. BZOJ 2049: [Sdoi2008]Cave 洞穴勘测 LCT

    2049: [Sdoi2008]Cave 洞穴勘测 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnli ...

  4. bzoj 2049: [Sdoi2008]Cave 洞穴勘测 动态树

    2049: [Sdoi2008]Cave 洞穴勘测 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 3119  Solved: 1399[Submit] ...

  5. 【LCT】BZOJ2049 [SDOI2008]Cave 洞穴勘测

    2049: [Sdoi2008]Cave 洞穴勘测 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 10059  Solved: 4863[Submit ...

  6. BZOJ_2049_[Sdoi2008]Cave 洞穴勘测_LCT

    BZOJ_2049_[Sdoi2008]Cave 洞穴勘测_LCT Description 辉辉热衷于洞穴勘测.某天,他按照地图来到了一片被标记为JSZX的洞穴群地区.经过初步勘测,辉辉发现这片区域由 ...

  7. bzoj 2049: [Sdoi2008]Cave 洞穴勘测 (LCT)

    链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2049 题面: 2049: [Sdoi2008]Cave 洞穴勘测 Time Limit: 1 ...

  8. BZOJ 2049: [Sdoi2008]Cave 洞穴勘测 (动态树入门)

    2049: [Sdoi2008]Cave 洞穴勘测 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 1528  Solved: 644[Submit][ ...

  9. 2049: [Sdoi2008]Cave 洞穴勘测

    2049: [Sdoi2008]Cave 洞穴勘测 Time Limit: 10 Sec  Memory Limit: 259 MB Submit: 7475  Solved: 3499 [Submi ...

随机推荐

  1. Wannafly Union Goodbye 2016-A//初识随机化~

    想来想去还是把这个题写下来了.自己在补题遇到了许多问题. 给出n(n<=1e5)个点,求是否存在多于p(p>=20)×n/100的点在一条直线上... 时限20s,多组数据,暴力至少n^2 ...

  2. 批量格式化json

    单个文件格式化工具: vscode和sublime都有格式化json的插件. 但是笔者遇到的情况是有几百个文件需要格式化,不可能每个文件都打开,进行分别格式化. 于是写了一个python脚本,非常强大 ...

  3. SpringMVC的controller层的方法返回值

    1.ModelAndView  既带着数据,又返回视图路劲 2.String 返回试图路径  model带数据  (官方或企业推荐使用此种方式 ,此方法符合解耦思想,即数据,视图,分离 MVC) 3. ...

  4. NodeJS基础入门-Event

    大多数Node.js核心API都采用惯用的异步事件驱动架构,其中某些类型的对象(触发器)会周期性地触发命名事件来调用函数对象(监听器). 例如,net.Server对象会在每次有新连接时触发事件;fs ...

  5. php读取不到https的域名

    因测试环境php遇到无法正常读取到https的域名,但是域名配置了ssl证书,故做如下排查. php测试代码如下 $config['base_url'] = ''; #开启调试模式 #echo &qu ...

  6. 序列内置方法详解(string/list/tuple)

    一.常用方法集合 1.1.string,字符串常用方法 以下举例是python2.7测试: 函数名称 作用 举例 str.capitalize() 字符串第一个字符如果是字母,则把字母替换为大写字母. ...

  7. pandas时间数据的集成处理

    工作中遇到的一个问题: 统计各地区新能源汽车的充电时长 数据来源是北理新源的单日全球的运行数据. 这里仅统计北上广重庆四个地区的 数据处理的代码就省略了 需要整理好的是4个dataframe(数据已保 ...

  8. sql执行过长,如何入手优化

    一条sql执行过长的时间,你如何优化,从哪些方面 1.查看sql是否涉及多表的联表或者子查询,如果有,看是否能进行业务拆分,相关字段冗余或者合并成临时表(业务和算法的优化)2.涉及链表的查询,是否能进 ...

  9. Linux下的硬件驱动——USB设备(转载)

    usb_bulk_msg函数 当对usb设备进行一次读或者写时,usb_bulk_msg 函数是非常有用的; 然而, 当你需要连续地对设备进行读/写时,建议你建立一个自己的urbs,同时将urbs 提 ...

  10. HDU - 4027 Can you answer these queries?(线段树)

    给定一个长度为n的序列,m次操作. 每次操作 可以将一个区间内的所有数字变为它的根号. 可以查询一个区间内所有元素的和. 线段树的初级应用. 如果把一个区间内的元素都改为它的根号的话,是需要每个数字都 ...