传送门

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

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

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

Code

#include<bits/stdc++.h>
using namespace std;
typedef unsigned int uint;
const int N=1e5+;
const uint mod=;
inline int read(){
int x=,w=;char ch=;
while(!isdigit(ch)) w|=ch=='-',ch=getchar();
while(isdigit(ch)) x=(x<<)+(x<<)+(ch^),ch=getchar();
return w?-x:x;
}
int f[N],sz[N],c[N][];
uint v[N],s[N],ml[N],ad[N];//int是会爆的
bool rv[N];
#define lc c[x][0]
#define rc c[x][1]
#define mul(x) x*=val,x%=mod
#define add(x) x+=val,x%=mod
//我习惯的写法是判断 not root
inline bool nrt(int x){return c[f[x]][]==x||c[f[x]][]==x;};
void pushup(int x){
s[x]=(s[lc]+s[rc]+v[x])%mod;
sz[x]=sz[lc]+sz[rc]+;
}
//自定义的优先级:乘法>加法>翻转
void Rev(int x){lc^=rc^=lc^=rc;rv[x]^=;};
void Mul(int x,uint val){mul(v[x]),mul(s[x]),mul(ml[x]),mul(ad[x]);}
void Add(int x,uint val){add(v[x]);add(ad[x]);val*=sz[x];val%=mod;add(s[x]);}
void pushdown(int x){
if(ml[x]^) Mul(lc,ml[x]),Mul(rc,ml[x]),ml[x]=;
if(ad[x]) Add(lc,ad[x]),Add(rc,ad[x]),ad[x]=;
if(rv[x]) Rev(lc),Rev(rc),rv[x]=;
}
//以下跟普通的LCT没两样
int get(int x){return x==c[f[x]][];}
void link(int x,int y,int d){c[x][d]=y;f[y]=x;}
void rotate(int x){
int y=f[x],z=f[y],d=get(x);
if(nrt(y)) c[z][get(y)]=x;f[x]=z;
//如果y=rt,说明y->z是一条虚边,也就是说x和z分属两棵不同的Splay,如果这样还连边z->x的话,后果emmm……
//但x->z必须连,因为就算y是根,把x旋上去后x就成根了,而LCT中一棵Spaly的根的父边一定是一条虚边(原树的根所属的Splay除外),相当于x继承了y连虚边的使命。。。
link(y,c[x][d^],d);
link(x,y,d^);
pushup(y),pushup(x);
}
int st[N],tp;
void splay(int x){
int t=x;
//手动用栈来pushdown
st[tp=]=t;
while(nrt(t)) st[++tp]=t=f[t];
while(tp) pushdown(st[tp--]);
for(;nrt(x);rotate(x)){
int y=f[x];
if(nrt(y)) get(x)^get(y)?rotate(x):rotate(y);
}
}
void access(int x){
for(int y=;x;x=f[y=x])
splay(x),c[x][]=y,pushup(x);
}
void makert(int x){
access(x),splay(x),Rev(x);
}
int findrt(int x){
access(x),splay(x);
while(lc) pushdown(x),x=lc;
splay(x);return x;
}
void split(int x,int y){
makert(x),access(y),splay(y);
}
void link(int x,int y){
makert(x);if(findrt(y)^x) f[x]=y;
}
void cut(int x,int y){
makert(x);
//在这道题中由于保证了cut操作合法因此应该可以不加判断
if(findrt(y)==x&&f[y]==x&&!c[y][]) f[y]=c[x][]=,pushup(x);
}
int n,m;
int main(){
n=read(),m=read();
for(int i=;i<=n;++i) v[i]=ml[i]=sz[i]=;
for(int i=;i<n;++i) link(read(),read());
char op[];int x,y;
while(m--){
scanf("%s",op);
x=read(),y=read();
switch(op[]){
case '+':split(x,y);Add(y,read());break;
case '-':cut(x,y);link(read(),read());break;
case '*':split(x,y);Mul(y,read());break;
case '/':split(x,y);cout<<s[y]<<endl;break;
}
}
return ;
}

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. linux连接Windows系统之项目连接

    在桥接模式下 在linux内需要设置 防火墙关闭 在Windows中连接 linux的ip连接 ***项目 在linux中命令行输入setup-->防火墙配置-->空格-->确定-- ...

  2. python_0基础开始_day11

    第十一节 一,函数名的第一类对象 函数名当作值,赋值给变量 print(函数名) 查看看书的内存地址 函数名可以当作容器中的元素 lis = []dic = {}def func():    prin ...

  3. Spring经典高频面试题,原来是长这个样子

    Spring经典高频面试题,原来是长这个样子 2019年08月23日 15:01:32 博文视点 阅读数 719   版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文 ...

  4. redis 学习(12)-- redis 发布订阅

    redis 发布订阅 发布订阅模式中的角色 发布者(publisher) 订阅者(subscriber) 频道(channel) 如图所示: 发布者发布消息到频道,订阅了频道的订阅者可以收到消息,订阅 ...

  5. List的Select 和Select().tolist()

    List<Person> delp = new List<Person> { ,Name=,Sign= }, ,Name= ,Sign=}, }; delp.Select(u ...

  6. Jenkins 入门系列--jenkins 介绍

    第一章 Jenkins是什么? Jenkins 是一个可扩展的持续集成引擎. 主要用于: l 持续.自动地构建/测试软件项目. l 监控一些定时执行的任务. Jenkins拥有的特性包括: l 易于安 ...

  7. 架构师成长之路5.3-Saltstack配置管理(State状态模块)

    点击架构师成长之路 架构师成长之路5.3-Saltstack配置管理(State状态模块) 配置管理工具: Pupper:1. 采用ruby编程语言:2. 安装环境相对较复杂:3.不支持远程执行,需要 ...

  8. Idea 汉化后定位和系统设置打不开到问题

    百度网盘:此汉化包已经修正过,拿来直接可以用 链接:https://pan.baidu.com/s/1wm3NbYSM9Gtsdu2EHQPMIA 密码:qdr3 1.系统设置(setting)外观选 ...

  9. mysql自增字段AUTO_INCREMENT重排或归零

    由于删除了某些记录行,导致自增字段不连续了,重排或归零的方法: 方法1:truncate table 你的表名//这样不但重新定位自增的字段,而且会将表里的数据全部删除,慎用! 方法2:delete ...

  10. Summer training round2 #7 (Training #23)

    A:约瑟夫环 套公式 B:线性筛素数 C:投骰子 概率DP F:有权无向图的生成树(边最大值和最小值只差最小) 直接kruskal G:状压BFS或者双向BFS H:模拟题 I:几何题 J:高斯消元