题目链接

LCT(良心总结)

  1. #include <cstdio>
  2. #include <cctype>
  3. #include <algorithm>
  4. #define gc() getchar()
  5. const int N=3e5+5;
  6. inline int read()
  7. {
  8. int now=0;register char c=gc();
  9. for(;!isdigit(c);c=gc());
  10. for(;isdigit(c);now=now*10+c-'0',c=gc());
  11. return now;
  12. }
  13. namespace LCT
  14. {
  15. #define lson son[x][0]
  16. #define rson son[x][1]
  17. int fa[N],val[N],sum[N],son[N][2],sk[N];
  18. bool tag[N];
  19. inline void Update(int x){
  20. sum[x]=sum[lson]^sum[rson]^val[x];
  21. }
  22. inline void Rev(int x){
  23. std::swap(lson,rson), tag[x]^=1;
  24. }
  25. inline void PushDown(int x){
  26. if(tag[x]) Rev(lson),Rev(rson),tag[x]=0;
  27. }
  28. inline bool n_root(int x){
  29. return son[fa[x]][0]==x||son[fa[x]][1]==x;
  30. }
  31. void Rotate(int x)
  32. {
  33. int a=fa[x],b=fa[a],l=son[a][1]==x,r=l^1;
  34. if(n_root(a)) son[b][son[b][1]==a]=x;
  35. if(son[x][r]) fa[son[x][r]]=a;
  36. fa[a]=x, fa[x]=b;
  37. son[a][l]=son[x][r], son[x][r]=a;
  38. Update(a), Update(x);
  39. }
  40. void Splay(int x)
  41. {
  42. int t=1,a=x,b; sk[1]=x;
  43. while(n_root(a)) sk[++t]=a=fa[a];//别写成while(fa[x])!
  44. while(t) PushDown(sk[t--]);
  45. while(n_root(x))
  46. {
  47. a=fa[x], b=fa[a];
  48. if(n_root(a)) Rotate(son[a][1]==x^son[b][1]==a?x:a);
  49. Rotate(x);
  50. }
  51. Update(x);//还是加上吧
  52. }
  53. void Access(int x){
  54. for(int pre=0; x; x=fa[pre=x])//pre=x老漏。。
  55. Splay(x), rson=pre, Update(x);
  56. }
  57. void Make_root(int x){
  58. Access(x), Splay(x), Rev(x);
  59. }
  60. void Split(int x,int y){
  61. Make_root(x), Access(y), Splay(y);
  62. }
  63. int Find_root(int x)
  64. {
  65. Access(x), Splay(x);
  66. while(lson) x=lson;
  67. // Splay(x);//需要保证复杂度?
  68. return x;
  69. }
  70. // int Get_fa(int x){
  71. // while(fa[x]) x=fa[x];
  72. // return x;
  73. // }
  74. // void Link(int x,int y){
  75. // if(Get_fa(x)!=Get_fa(y)) Make_root(x),fa[x]=y;//Get_fa()有点慢啊
  76. // }
  77. void Link(int x,int y)
  78. {
  79. Make_root(x);
  80. if(Find_root(y)!=x) fa[x]=y;//连的是轻边!不要加rson=y;
  81. }
  82. void Cut(int x,int y)
  83. {
  84. Make_root(x);
  85. if(Find_root(y)==x&&fa[x]==y&&!rson)
  86. fa[x]=son[y][0]=0, Update(y);
  87. // if(Find_root(y)==x&&fa[y]==x&&!son[y][0])//若Find_root()中把根又转回去了
  88. // fa[y]=rson=0, Update(x);
  89. }
  90. }
  91. int main()
  92. {
  93. int n=read(),m=read();
  94. for(int i=1; i<=n; ++i) LCT::val[i]=read();
  95. int opt,x,y;
  96. while(m--)
  97. {
  98. opt=read(),x=read(),y=read();
  99. if(!opt) LCT::Split(x,y), printf("%d\n",LCT::sum[y]);
  100. else if(opt==1) LCT::Link(x,y);
  101. else if(opt==2) LCT::Cut(x,y);
  102. else LCT::Splay(x), LCT::val[x]=y;/*sum[y]^=val[x]^y, val[x]=y*/ //这步在Split()(查询时)的Splay()中 最后还会Update()
  103. }
  104. return 0;
  105. }

第二次(2018.4.5):

  1. #include <cstdio>
  2. #include <cctype>
  3. #include <algorithm>
  4. #define gc() getchar()
  5. const int N=3e5+5;
  6. inline int read()
  7. {
  8. int now=0;register char c=gc();
  9. for(;!isdigit(c);c=gc());
  10. for(;isdigit(c);now=now*10+c-'0',c=gc());
  11. return now;
  12. }
  13. namespace LCT
  14. {
  15. #define lson son[x][0]
  16. #define rson son[x][1]
  17. int fa[N],son[N][2],sum[N],val[N],sk[N];
  18. bool rev[N];
  19. inline void Update(int x){
  20. sum[x]=sum[lson]^sum[rson]^val[x];
  21. }
  22. inline bool n_root(int x){
  23. return son[fa[x]][0]==x||son[fa[x]][1]==x;
  24. }
  25. inline void Rev(int x){
  26. std::swap(lson,rson), rev[x]^=1;
  27. }
  28. inline void PushDown(int x){
  29. if(rev[x]) Rev(lson),Rev(rson),rev[x]=0;
  30. }
  31. void Rotate(int x)
  32. {
  33. int a=fa[x],b=fa[a],l=son[a][1]==x,r=l^1;
  34. if(n_root(a)) son[b][son[b][1]==a]=x;
  35. if(son[x][r]) fa[son[x][r]]=a;
  36. fa[a]=x, fa[x]=b, son[a][l]=son[x][r], son[x][r]=a;
  37. Update(a);
  38. }
  39. void Splay(int x)
  40. {
  41. int t=1,a=x; sk[1]=x;
  42. while(n_root(a)) sk[++t]=a=fa[a];
  43. while(t) PushDown(sk[t--]);
  44. while(n_root(x))
  45. {
  46. if(n_root(a=fa[x])) Rotate(son[a][1]==x^son[fa[a]][1]==a?x:a);
  47. Rotate(x);
  48. }
  49. Update(x);
  50. }
  51. void Access(int x){
  52. for(int pre=0; x; x=fa[pre=x])
  53. Splay(x), rson=pre, Update(x);
  54. }
  55. void Make_root(int x){
  56. Access(x), Splay(x), Rev(x);
  57. }
  58. void Split(int x,int y){
  59. Make_root(x), Access(y), Splay(y);
  60. }
  61. int Find_root(int x)
  62. {
  63. Access(x), Splay(x);
  64. while(lson) x=lson;
  65. return x;
  66. }
  67. void Link(int x,int y)
  68. {
  69. Make_root(x);
  70. if(Find_root(y)!=x) fa[x]=y;
  71. }
  72. void Cut(int x,int y)
  73. {
  74. Make_root(x);
  75. if(Find_root(y)==x&&fa[x]==y&&!rson)
  76. fa[x]=son[y][0]=0, Update(y);
  77. }
  78. }
  79. using namespace LCT;
  80. int main()
  81. {
  82. int n=read(),m=read(),opt,x,y;
  83. for(int i=1; i<=n; ++i) val[i]=read();
  84. while(m--)
  85. switch(opt=read(),x=read(),y=read(),opt)
  86. {
  87. case 0: Split(x,y),printf("%d\n",sum[y]); break;
  88. case 1: Link(x,y); break;
  89. case 2: Cut(x,y); break;
  90. case 3: Splay(x), val[x]=y; break;
  91. }
  92. return 0;
  93. }

第三次(2018.6.28):竟然快了那么多,好像没什么太大变化啊。。

  1. //592ms 3.76MB
  2. #include <cstdio>
  3. #include <cctype>
  4. #include <algorithm>
  5. //#define gc() getchar()
  6. #define MAXIN 150000
  7. #define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
  8. const int N=3e5+5;
  9. char IN[MAXIN],*SS=IN,*TT=IN;
  10. namespace LCT
  11. {
  12. #define lson son[x][0]
  13. #define rson son[x][1]
  14. int fa[N],son[N][2],val[N],sum[N],sk[N];
  15. bool rev[N];
  16. inline void Update(int x){
  17. sum[x]=sum[lson]^sum[rson]^val[x];
  18. }
  19. inline void Rev(int x){
  20. std::swap(lson,rson), rev[x]^=1;
  21. }
  22. inline void PushDown(int x){
  23. if(rev[x]) Rev(lson), Rev(rson), rev[x]=0;
  24. }
  25. inline bool n_root(int x){
  26. return son[fa[x]][0]==x||son[fa[x]][1]==x;
  27. }
  28. void Rotate(int x)
  29. {
  30. int a=fa[x],b=fa[a],l=son[a][1]==x,r=l^1;
  31. if(n_root(a)) son[b][son[b][1]==a]=x;
  32. if(son[x][r]) fa[son[x][r]]=a;
  33. fa[x]=b, fa[a]=x, son[a][l]=son[x][r], son[x][r]=a;
  34. Update(a);
  35. }
  36. void Splay(int x)
  37. {
  38. int a=x,t=1; sk[1]=x;
  39. while(n_root(a)) sk[++t]=a=fa[a];
  40. while(t) PushDown(sk[t--]);
  41. while(n_root(x))
  42. {
  43. if(n_root(a=fa[x])) Rotate(son[a][1]==x^son[fa[a]][1]==a?x:a);
  44. Rotate(x);
  45. }
  46. Update(x);
  47. }
  48. void Access(int x){
  49. for(int pre=0; x; x=fa[pre=x])
  50. Splay(x), rson=pre, Update(x);
  51. }
  52. void Make_root(int x){
  53. Access(x), Splay(x), Rev(x);
  54. }
  55. void Split(int x,int y){
  56. Make_root(x), Access(y), Splay(y);
  57. }
  58. int Find_root(int x)
  59. {
  60. Access(x), Splay(x);
  61. while(lson) x=lson;
  62. return x;
  63. }
  64. void Link(int x,int y)
  65. {
  66. Make_root(x);
  67. if(Find_root(y)!=x) fa[x]=y;
  68. }
  69. void Cut(int x,int y)
  70. {
  71. Make_root(x);
  72. if(Find_root(y)==x&&!rson&&fa[x]==y) son[y][0]=fa[x]=0, Update(y);
  73. }
  74. }
  75. using namespace LCT;
  76. inline int read()
  77. {
  78. int now=0;register char c=gc();
  79. for(;!isdigit(c);c=gc());
  80. for(;isdigit(c);now=now*10+c-'0',c=gc());
  81. return now;
  82. }
  83. int main()
  84. {
  85. int n=read(), m=read();
  86. for(int i=1; i<=n; ++i) val[i]=read();
  87. int opt,x,y;
  88. while(m--){
  89. switch(opt=read(),x=read(),y=read(),opt){
  90. case 0: Split(x,y), printf("%d\n",sum[y]); break;
  91. case 1: Link(x,y); break;
  92. case 2: Cut(x,y); break;
  93. case 3: Splay(x), val[x]=y; break;
  94. }
  95. }
  96. return 0;
  97. }

19.4.5

  1. //520ms 2984KB
  2. #include <cstdio>
  3. #include <cctype>
  4. #include <algorithm>
  5. #define gc() getchar()
  6. #define MAXIN 300000
  7. //#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
  8. typedef long long LL;
  9. const int N=3e5+5;
  10. char IN[MAXIN],*SS=IN,*TT=IN;
  11. struct LCT
  12. {
  13. #define ls son[x][0]
  14. #define rs son[x][1]
  15. int fa[N],son[N][2],sum[N],val[N],sk[N];
  16. bool rev[N];
  17. inline void Update(int x)
  18. {
  19. sum[x]=sum[ls]^sum[rs]^val[x];
  20. }
  21. inline bool n_root(int x)
  22. {
  23. return son[fa[x]][0]==x||son[fa[x]][1]==x;
  24. }
  25. inline void Rev(int x)
  26. {
  27. std::swap(ls,rs), rev[x]^=1;
  28. }
  29. inline void PushDown(int x)
  30. {
  31. if(rev[x]) Rev(ls), Rev(rs), rev[x]=0;
  32. }
  33. void Rotate(int x)
  34. {
  35. int a=fa[x],b=fa[a],l=son[a][1]==x,r=l^1;
  36. if(n_root(a)) son[b][son[b][1]==a]=x;
  37. if(son[x][r]) fa[son[x][r]]=a;
  38. fa[x]=b, fa[a]=x, son[a][l]=son[x][r], son[x][r]=a;
  39. Update(a);
  40. }
  41. void Splay(int x)
  42. {
  43. int t=1,a=x; sk[1]=a;
  44. while(n_root(a)) sk[++t]=a=fa[a];
  45. while(t) PushDown(sk[t--]);
  46. while(n_root(x))
  47. {
  48. if(n_root(a=fa[x])) Rotate(son[a][0]==x^son[fa[a]][0]==a?x:a);
  49. Rotate(x);
  50. }
  51. Update(x);
  52. }
  53. void Access(int x)
  54. {
  55. for(int pre=0; x; x=fa[pre=x])
  56. Splay(x), rs=pre, Update(x);
  57. }
  58. void MakeRoot(int x)
  59. {
  60. Access(x), Splay(x), Rev(x);
  61. }
  62. void Split(int x,int y)
  63. {
  64. MakeRoot(x), Access(y), Splay(y);
  65. }
  66. int FindRoot(int x)
  67. {
  68. Access(x), Splay(x);
  69. while(ls) x=ls;
  70. return x;
  71. }
  72. void Link(int x,int y)
  73. {
  74. MakeRoot(x);
  75. if(FindRoot(y)!=x) fa[x]=y;
  76. }
  77. void Cut(int x,int y)
  78. {
  79. MakeRoot(x);
  80. if(FindRoot(y)==x&&fa[x]==y&&!rs) fa[x]=son[y][0]=0, Update(y);
  81. }
  82. }T;
  83. inline int read()
  84. {
  85. int now=0;register char c=gc();
  86. for(;!isdigit(c);c=gc());
  87. for(;isdigit(c);now=now*10+c-48,c=gc());
  88. return now;
  89. }
  90. int main()
  91. {
  92. int n=read(),q=read();
  93. for(int i=1; i<=n; ++i) T.val[i]=read();
  94. for(int x,y; q--; )
  95. switch(read())
  96. {
  97. case 0: x=read(),y=read(),T.Split(x,y),printf("%d\n",T.sum[y]); break;
  98. case 1: x=read(),y=read(),T.Link(x,y); break;
  99. case 2: x=read(),y=read(),T.Cut(x,y); break;
  100. case 3: T.Splay(x=read()),T.val[x]=read(); break;
  101. }
  102. return 0;
  103. }

洛谷.3690.[模板]Link Cut Tree(动态树)的更多相关文章

  1. LCT总结——概念篇+洛谷P3690[模板]Link Cut Tree(动态树)(LCT,Splay)

    为了优化体验(其实是强迫症),蒟蒻把总结拆成了两篇,方便不同学习阶段的Dalao们切换. LCT总结--应用篇戳这里 概念.性质简述 首先介绍一下链剖分的概念(感谢laofu的讲课) 链剖分,是指一类 ...

  2. 洛谷P3690 [模板] Link Cut Tree [LCT]

    题目传送门 Link Cut Tree 题目背景 动态树 题目描述 给定n个点以及每个点的权值,要你处理接下来的m个操作.操作有4种.操作从0到3编号.点从1到n编号. 0:后接两个整数(x,y),代 ...

  3. Link Cut Tree 动态树 小结

    动态树有些类似 树链剖分+并查集 的思想,是用splay维护的 lct的根是动态的,"轻重链"也是动态的,所以并没有真正的轻重链 动态树的操作核心是把你要把 修改/询问/... 等 ...

  4. 洛谷P3690 Link Cut Tree (动态树)

    干脆整个LCT模板吧. 缺个链上修改和子树操作,链上修改的话join(u,v)然后把v splay到树根再打个标记就好. 至于子树操作...以后有空的话再学(咕咕咕警告) #include<bi ...

  5. LCT(link cut tree) 动态树

    模板参考:https://blog.csdn.net/saramanda/article/details/55253627 综合各位大大博客后整理的模板: #include<iostream&g ...

  6. 洛谷P2633 Count on a tree(主席树上树)

    题目描述 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个询问的答案,初始为0,即第一个 ...

  7. 模板Link Cut Tree (动态树)

    题目描述 给定N个点以及每个点的权值,要你处理接下来的M个操作.操作有4种.操作从0到3编号.点从1到N编号. 0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor和.保证x到y是联 ...

  8. 洛谷 P2633 Count on a tree 主席树

    在一棵树上,我们要求点 $(u,v)$ 之间路径的第$k$大数. 对于点 $i$  ,建立 $i$  到根节点的一棵前缀主席树. 简单容斥后不难得出结果为$sumv[u]+sumv[v]−sumv[l ...

  9. 洛谷P2633 Count on a tree 主席树

    传送门:主席树 解题报告: 传送门! umm这题我还麻油开始做 所以 先瞎扯一波我的想法,如果错了我就当反面教材解释这种典型错误,对了我就不管了QwQ 就直接dfs,在dfs的过程中建树 然后就直接查 ...

随机推荐

  1. python3之Django多数据库

    1.定义数据库 在django项目中, 一个工程中存在多个APP应用很常见:有时候希望不同的APP连接不同的数据库,这个时候需要建立多个数据库连接.在Django的setting中使用DATABASE ...

  2. 【转】OpenCV对图片中的RotatedRect进行填充

    函数名:full_rotated_rect 函数参数: image输入图像,rect希望在图像中填充的RotatedRect,color填充的颜色 主要的思路是:先找到RotatedRect的四个顶点 ...

  3. 028_rync和inotify实现实时备份

    一.服务节点安装inotify-tools. 确保系统后以下输出=> [root@xxxx]# ll /proc/sys/fs/inotify/ total 0 -rw-r--r-- 1 roo ...

  4. nginx报错:403 Forbidden 并且访问首页index.php是下载文件的状态

    nginx报错:403 Forbidden 并且访问首页index.php是下载文件的状态,不能正常解析php 系统有其他两个站访问是正常的 看日志没有看到明显的错误 搜索了下: 答案如下: php的 ...

  5. Centos6安装FreeSWITCH 1.5时./configure问题解决记录

    系统:Centos 6.4 64位: FreeSWITCH版本:1.5 具体的安装过程参考FreeSWITCH 官网wiki (也可以参考我的博客<Centos6安装FreeSWITCH> ...

  6. 初识numpy

    from numpy import *   导入numpy包 random可以生成随机数组 通过mat函数,将数组转换成矩阵,可以对矩阵进行求逆计算等.其中.I操作实现了矩阵求逆计算操作. 执行矩阵乘 ...

  7. JAVA Random 随机类

    nextInt 方法 得到一个随机整数, 可以指定范围 package object; import static net.util.Print.*; import java.util.Random; ...

  8. ECLIPSE 导入外部文件或源码包

    步骤: 点击Project->Properties->Libraries->Add External Class Folder.. ->选择你的文件路径->确定 注:如果 ...

  9. Windows安装使用Openssl

    1.什么是openssl? 2.下载安装 三方下载地址 备用64位和32位下载地址 选择32位或者64位合适的版本下载,例如Win64OpenSSL_Light-1_0_2h.exe: 设置环境变量, ...

  10. 学习Struts2经验总结

    一.struts 访问路径问题 1) Struts2的思想:主要围着“action”转,只要找到“action”它就知道自己该干嘛了. 首先配置struts.xml ,我们可以明白的看到,action ...