指针版P3690 【模板】Link Cut Tree (动态树)
题面
题解
鉴于数组版实在是太慢我用指针版重新写了一遍
代码基本是借鉴了lxl某道关于\(LCT\)的题
//minamoto
#include<bits/stdc++.h>
#define R register
#define inline __inline__ __attribute__((always_inline))
#define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
#define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
using namespace std;
char buf[1<<21],*p1=buf,*p2=buf;
inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
int read(){
R int res,f=1;R char ch;
while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
return res*f;
}
inline int getop(){R char ch;while((ch=getc())>'9'||ch<'0');return ch-'0';}
char sr[1<<21],z[20];int C=-1,Z=0;
inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
void print(R int x){
if(C>1<<20)Ot();if(x<0)sr[++C]='-',x=-x;
while(z[++Z]=x%10+48,x/=10);
while(sr[++C]=z[Z],--Z);sr[++C]='\n';
}
const int N=3e5+5;
struct node;typedef node* ptr;
inline void swap(R ptr &x,R ptr &y){R ptr t=x;x=y,y=t;}
struct node{
ptr lc,rc,fa;int s,v,r;
inline node();
inline void ppd(){swap(lc,rc),r^=1;}
inline void pd(){if(r)lc->ppd(),rc->ppd(),r=0;}
inline ptr upd(){return s=lc->s^rc->s^v,this;}
}e[N];
inline node::node(){fa=lc=rc=e;}
inline bool isrt(R ptr p){return p->fa->lc!=p&&p->fa->rc!=p;}
void rotate(ptr p){
ptr s=p->fa,t=s->fa;
if(!isrt(s))(t->lc==s?t->lc:t->rc)=p;
p->fa=t,s->fa=p;
if(s->lc==p)s->lc=p->rc,p->rc->fa=s,p->rc=s->upd();
else s->rc=p->lc,p->lc->fa=s,p->lc=s->upd();
}
void push(ptr p){if(!isrt(p))push(p->fa);p->pd();}
ptr splay(ptr p){
push(p);
while(!isrt(p)){
if(!isrt(p->fa))rotate(p->fa->lc==p^p->fa->fa->lc==p->fa?p:p->fa);
rotate(p);
}
return p->upd();
}
ptr exp(ptr p){
ptr s=e;
while(p!=e)splay(p)->rc=s,s=p->upd(),p=p->fa;
return s;
}
inline void makert(ptr p){exp(p),splay(p)->ppd();}
inline ptr split(ptr s,ptr t){return makert(s),exp(t);}
ptr findrt(ptr p){
exp(p),splay(p)->pd();
while(p->lc!=e)(p=p->lc)->pd();
return p;
}
void link(ptr s,ptr t){
makert(s);
if(findrt(t)!=s)s->fa=t;
//虚儿子接上之后根本不用upd
}
void cut(ptr s,ptr t){
makert(s);
if(findrt(t)==s&&s->fa==t&&s->rc==e)
s->fa=t->lc=e,t->upd();
}
int n,m,op,u,v;
int main(){
// freopen("testdata.in","r",stdin);
// freopen("testdata.out","w",stdout);
n=read(),m=read();
fp(i,1,n)(e+i)->v=read(),(e+i)->upd();
while(m--){
op=getop(),u=read(),v=read();
switch(op){
case 0:print(split(e+u,e+v)->s);break;
case 1:link(e+u,e+v);break;
case 2:cut(e+u,e+v);break;
case 3:splay(e+u),(e+u)->v=v,(e+u)->upd();break;
}
}
return Ot(),0;
}
指针版P3690 【模板】Link Cut Tree (动态树)的更多相关文章
- LCT总结——概念篇+洛谷P3690[模板]Link Cut Tree(动态树)(LCT,Splay)
为了优化体验(其实是强迫症),蒟蒻把总结拆成了两篇,方便不同学习阶段的Dalao们切换. LCT总结--应用篇戳这里 概念.性质简述 首先介绍一下链剖分的概念(感谢laofu的讲课) 链剖分,是指一类 ...
- 洛谷.3690.[模板]Link Cut Tree(动态树)
题目链接 LCT(良心总结) #include <cstdio> #include <cctype> #include <algorithm> #define gc ...
- 洛谷P3690 [模板] Link Cut Tree [LCT]
题目传送门 Link Cut Tree 题目背景 动态树 题目描述 给定n个点以及每个点的权值,要你处理接下来的m个操作.操作有4种.操作从0到3编号.点从1到n编号. 0:后接两个整数(x,y),代 ...
- Link Cut Tree 动态树 小结
动态树有些类似 树链剖分+并查集 的思想,是用splay维护的 lct的根是动态的,"轻重链"也是动态的,所以并没有真正的轻重链 动态树的操作核心是把你要把 修改/询问/... 等 ...
- 洛谷P3690 Link Cut Tree (动态树)
干脆整个LCT模板吧. 缺个链上修改和子树操作,链上修改的话join(u,v)然后把v splay到树根再打个标记就好. 至于子树操作...以后有空的话再学(咕咕咕警告) #include<bi ...
- LCT(link cut tree) 动态树
模板参考:https://blog.csdn.net/saramanda/article/details/55253627 综合各位大大博客后整理的模板: #include<iostream&g ...
- 模板Link Cut Tree (动态树)
题目描述 给定N个点以及每个点的权值,要你处理接下来的M个操作.操作有4种.操作从0到3编号.点从1到N编号. 0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor和.保证x到y是联 ...
- 【刷题】洛谷 P3690 【模板】Link Cut Tree (动态树)
题目背景 动态树 题目描述 给定n个点以及每个点的权值,要你处理接下来的m个操作.操作有4种.操作从0到3编号.点从1到n编号. 0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor ...
- P3690 【模板】Link Cut Tree (动态树)
P3690 [模板]Link Cut Tree (动态树) 认父不认子的lct 注意:不 要 把 $fa[x]$和$nrt(x)$ 混 在 一 起 ! #include<cstdio> v ...
- LuoguP3690 【模板】Link Cut Tree (动态树) LCT模板
P3690 [模板]Link Cut Tree (动态树) 题目背景 动态树 题目描述 给定n个点以及每个点的权值,要你处理接下来的m个操作.操作有4种.操作从0到3编号.点从1到n编号. 0:后接两 ...
随机推荐
- VS Code 界面语言设置
首先Ctrl+shift+p打开命令面板. 输入配置显示语言 回车 更改locale即可更改页面显语言(更改后需重启软件). 目前支持如下语言 Display Language Locale Engl ...
- MyBatis ehcache二级缓存
ehcache二级缓存的开启步骤: 1.导入jar 2.在映射文件中指定用的哪个缓存 3.加一个配置文件,这个配置文件在ehcache jar包中就有 使增删改对二级缓存不刷新: 对一级缓存没有用的, ...
- python 把txt文件分隔成0.8和0.2的比例的新文件
from math import sqrt import randomimport osfrom sklearn import cross_validation os.chdir("/*&q ...
- ConcurrentDictionary内部机制粗解
ConcurrentDictionary是线程安全类,是什么在保证? 内部类 private class Tables { internal readonly Node[] m_buckets; // ...
- 在制MO未取到FP
原因:今天在制MO未取进去原因为业务人员维护验货客户尾缀时维护ZZ导致,需更新为C开头即可 SELECT * FROM IN_SFCHEADER WHERE MO_ID in('00110051832 ...
- 一些js知识点总结
1. 函数声明与函数表达式 解析器在像执行环境中加载数据时,会先读取函数声明,并使其在执行任何代码之前都可以访问,对于函数表达式,必须等到解析器执行到它所在的代码行,才会真正被执行. 例: alert ...
- 最多有k个不同字符的最长子字符串 · Longest Substring with at Most k Distinct Characters(没提交)
[抄题]: 给定一个字符串,找到最多有k个不同字符的最长子字符串.eg:eceba, k = 3, return eceb [暴力解法]: 时间分析: 空间分析: [思维问题]: 怎么想到两根指针的: ...
- Step By Step Hibernate Tutorial Using eclipse WTP[z]
[shivasoft.in/blog/sql/myqsl/step-by-step-hibernate-tutorial-using-eclipse-wtp/] Hibernate is the O ...
- Halcon阈值化算子dual_threshold和var_threshold的理解
Halcon中阈值二值化的算子众多,通常用得最多的有threshold.binary_threshold.dyn_threshold等. threshold是最简单的阈值分割算子,理解最为简单:bin ...
- send anywhere真的好用啊
手机和电脑互传文件,方便很多.