传送门

这是一道LCT的板子题,说白了就是在LCT上支持线段树2的操作。

所以我只是来存一个板子,并不会讲什么(再说我也不会,只能误人子弟2333)。

不过代码里的注释可以参考一下。

Code

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. typedef unsigned int uint;
  4. const int N=1e5+;
  5. const uint mod=;
  6. inline int read(){
  7. int x=,w=;char ch=;
  8. while(!isdigit(ch)) w|=ch=='-',ch=getchar();
  9. while(isdigit(ch)) x=(x<<)+(x<<)+(ch^),ch=getchar();
  10. return w?-x:x;
  11. }
  12. int f[N],sz[N],c[N][];
  13. uint v[N],s[N],ml[N],ad[N];//int是会爆的
  14. bool rv[N];
  15. #define lc c[x][0]
  16. #define rc c[x][1]
  17. #define mul(x) x*=val,x%=mod
  18. #define add(x) x+=val,x%=mod
  19. //我习惯的写法是判断 not root
  20. inline bool nrt(int x){return c[f[x]][]==x||c[f[x]][]==x;};
  21. void pushup(int x){
  22. s[x]=(s[lc]+s[rc]+v[x])%mod;
  23. sz[x]=sz[lc]+sz[rc]+;
  24. }
  25. //自定义的优先级:乘法>加法>翻转
  26. void Rev(int x){lc^=rc^=lc^=rc;rv[x]^=;};
  27. void Mul(int x,uint val){mul(v[x]),mul(s[x]),mul(ml[x]),mul(ad[x]);}
  28. void Add(int x,uint val){add(v[x]);add(ad[x]);val*=sz[x];val%=mod;add(s[x]);}
  29. void pushdown(int x){
  30. if(ml[x]^) Mul(lc,ml[x]),Mul(rc,ml[x]),ml[x]=;
  31. if(ad[x]) Add(lc,ad[x]),Add(rc,ad[x]),ad[x]=;
  32. if(rv[x]) Rev(lc),Rev(rc),rv[x]=;
  33. }
  34. //以下跟普通的LCT没两样
  35. int get(int x){return x==c[f[x]][];}
  36. void link(int x,int y,int d){c[x][d]=y;f[y]=x;}
  37. void rotate(int x){
  38. int y=f[x],z=f[y],d=get(x);
  39. if(nrt(y)) c[z][get(y)]=x;f[x]=z;
  40. //如果y=rt,说明y->z是一条虚边,也就是说x和z分属两棵不同的Splay,如果这样还连边z->x的话,后果emmm……
  41. //但x->z必须连,因为就算y是根,把x旋上去后x就成根了,而LCT中一棵Spaly的根的父边一定是一条虚边(原树的根所属的Splay除外),相当于x继承了y连虚边的使命。。。
  42. link(y,c[x][d^],d);
  43. link(x,y,d^);
  44. pushup(y),pushup(x);
  45. }
  46. int st[N],tp;
  47. void splay(int x){
  48. int t=x;
  49. //手动用栈来pushdown
  50. st[tp=]=t;
  51. while(nrt(t)) st[++tp]=t=f[t];
  52. while(tp) pushdown(st[tp--]);
  53. for(;nrt(x);rotate(x)){
  54. int y=f[x];
  55. if(nrt(y)) get(x)^get(y)?rotate(x):rotate(y);
  56. }
  57. }
  58. void access(int x){
  59. for(int y=;x;x=f[y=x])
  60. splay(x),c[x][]=y,pushup(x);
  61. }
  62. void makert(int x){
  63. access(x),splay(x),Rev(x);
  64. }
  65. int findrt(int x){
  66. access(x),splay(x);
  67. while(lc) pushdown(x),x=lc;
  68. splay(x);return x;
  69. }
  70. void split(int x,int y){
  71. makert(x),access(y),splay(y);
  72. }
  73. void link(int x,int y){
  74. makert(x);if(findrt(y)^x) f[x]=y;
  75. }
  76. void cut(int x,int y){
  77. makert(x);
  78. //在这道题中由于保证了cut操作合法因此应该可以不加判断
  79. if(findrt(y)==x&&f[y]==x&&!c[y][]) f[y]=c[x][]=,pushup(x);
  80. }
  81. int n,m;
  82. int main(){
  83. n=read(),m=read();
  84. for(int i=;i<=n;++i) v[i]=ml[i]=sz[i]=;
  85. for(int i=;i<n;++i) link(read(),read());
  86. char op[];int x,y;
  87. while(m--){
  88. scanf("%s",op);
  89. x=read(),y=read();
  90. switch(op[]){
  91. case '+':split(x,y);Add(y,read());break;
  92. case '-':cut(x,y);link(read(),read());break;
  93. case '*':split(x,y);Mul(y,read());break;
  94. case '/':split(x,y);cout<<s[y]<<endl;break;
  95. }
  96. }
  97. return ;
  98. }

LCT模板

[洛谷P1501] [国家集训队]Tree II(LCT模板)的更多相关文章

  1. 洛谷P1501 [国家集训队]Tree II(LCT)

    题目描述 一棵n个点的树,每个点的初始权值为1.对于这棵树有q个操作,每个操作为以下四种操作之一: + u v c:将u到v的路径上的点的权值都加上自然数c: - u1 v1 u2 v2:将树中原有的 ...

  2. 洛谷 P1501 [国家集训队]Tree II 解题报告

    P1501 [国家集训队]Tree II 题目描述 一棵\(n\)个点的树,每个点的初始权值为\(1\).对于这棵树有\(q\)个操作,每个操作为以下四种操作之一: + u v c:将\(u\)到\( ...

  3. 洛谷P1501 [国家集训队]Tree II(LCT,Splay)

    洛谷题目传送门 关于LCT的其它问题可以参考一下我的LCT总结 一道LCT很好的练习放懒标记技巧的题目. 一开始看到又做加法又做乘法的时候我是有点mengbi的. 然后我想起了模板线段树2...... ...

  4. 洛谷P1501 [国家集训队]Tree II(打标记lct)

    题目描述 一棵n个点的树,每个点的初始权值为1.对于这棵树有q个操作,每个操作为以下四种操作之一: + u v c:将u到v的路径上的点的权值都加上自然数c: - u1 v1 u2 v2:将树中原有的 ...

  5. 洛谷.1501.[国家集训队]Tree II(LCT)

    题目链接 日常zz被define里没取模坑 //标记下放同线段树 注意51061^2 > 2147483647,要开unsigned int //*sz[]别忘了.. #include < ...

  6. 【刷题】洛谷 P1501 [国家集训队]Tree II

    题目描述 一棵n个点的树,每个点的初始权值为1.对于这棵树有q个操作,每个操作为以下四种操作之一: + u v c:将u到v的路径上的点的权值都加上自然数c: - u1 v1 u2 v2:将树中原有的 ...

  7. [洛谷P1501][国家集训队]Tree II

    题目大意:给一棵树,有四种操作: $+\;u\;v\;c:$将路径$u->v$区间加$c$ $-\;u_1\;v_1\;u_2\;v_2:$将边$u_1-v_1$切断,改成边$u_2-v_2$, ...

  8. 洛谷 P1501 [国家集训队]Tree II

    看来这个LCT板子并没有什么问题 #include<cstdio> #include<algorithm> using namespace std; typedef long ...

  9. 洛谷 P1501 [国家集训队]Tree II Link-Cut-Tree

    Code: #include <cstdio> #include <algorithm> #include <cstring> #include <strin ...

随机推荐

  1. python基础_面向对象

    面向对象定义 把一组数据结构和处理它们的方法组成对象(object),把相同行为的对象归纳为类(class),通过类的封装(encapsulation)隐藏内部细节,通过继承(inheritance) ...

  2. HTML5自学

    1.1   标题文本 在HTML5中,文本的结构除了以行和段落出现之外,还可以作为标题存在,通常一篇文档最基本的结构就是由不同级别的标题和正文组成的. 例如1:(中国门户网站) https://www ...

  3. gson 带泛型的转换

    json转对象 public static <T> T json2Obj(String json, Class<T> cls) { Gson gson = new Gson() ...

  4. 常见Http访问错误小结

    4xx 客户端错误# 400 bad request 错误的请求 # 401 未携带身份信息 # 403 forbidden 权限不够 # 404 Not Found# 405 请求方式不允许 5xx ...

  5. Altium Designer 编译原理图出现has no driving source警告解决办法

    版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明. 作者:struct_mooc 博客地址:https://www.cnblogs.com/stru ...

  6. 多线程编程-- part 9 信号量:Semaphore

    Semaphore简介 Semaphore是一个计数信号量,它的本质是一个"共享锁". 信号量维护了一个信号量许可集.线程可以通过调用acquire()来获取信号量的许可:当信号量 ...

  7. [转] JAVA分为三个体系,JavaSE,JavaEE,JavaME(J2ME)的区别以及各个版

        Java SE(JavaPlatform,Standard Edition).Java SE 以前称为 J2SE.它允许开发和部署在桌面.服务器.嵌入式环境和实时环境中使用的 Java 应用程 ...

  8. Java定义队结构,实现入队、出队操作

    package com.example.demo; import java.util.ArrayList; public class Queue { ArrayList<Object> l ...

  9. C#实现下载Demo

    using System; using System.Data; using System.Configuration; using System.Web; using System.Web.Secu ...

  10. zencart只有购买过此产品的客户才能评价产品

    当前登录的客户买过此产品时,才显示评价按钮: <?php $rev_query = "select count(*) as count from orders o ,orders_pr ...