洛谷.3690.[模板]Link Cut Tree(动态树)
#include <cstdio>
#include <cctype>
#include <algorithm>
#define gc() getchar()
const int N=3e5+5;
inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
namespace LCT
{
#define lson son[x][0]
#define rson son[x][1]
int fa[N],val[N],sum[N],son[N][2],sk[N];
bool tag[N];
inline void Update(int x){
sum[x]=sum[lson]^sum[rson]^val[x];
}
inline void Rev(int x){
std::swap(lson,rson), tag[x]^=1;
}
inline void PushDown(int x){
if(tag[x]) Rev(lson),Rev(rson),tag[x]=0;
}
inline bool n_root(int x){
return son[fa[x]][0]==x||son[fa[x]][1]==x;
}
void Rotate(int x)
{
int a=fa[x],b=fa[a],l=son[a][1]==x,r=l^1;
if(n_root(a)) son[b][son[b][1]==a]=x;
if(son[x][r]) fa[son[x][r]]=a;
fa[a]=x, fa[x]=b;
son[a][l]=son[x][r], son[x][r]=a;
Update(a), Update(x);
}
void Splay(int x)
{
int t=1,a=x,b; sk[1]=x;
while(n_root(a)) sk[++t]=a=fa[a];//别写成while(fa[x])!
while(t) PushDown(sk[t--]);
while(n_root(x))
{
a=fa[x], b=fa[a];
if(n_root(a)) Rotate(son[a][1]==x^son[b][1]==a?x:a);
Rotate(x);
}
Update(x);//还是加上吧
}
void Access(int x){
for(int pre=0; x; x=fa[pre=x])//pre=x老漏。。
Splay(x), rson=pre, Update(x);
}
void Make_root(int x){
Access(x), Splay(x), Rev(x);
}
void Split(int x,int y){
Make_root(x), Access(y), Splay(y);
}
int Find_root(int x)
{
Access(x), Splay(x);
while(lson) x=lson;
// Splay(x);//需要保证复杂度?
return x;
}
// int Get_fa(int x){
// while(fa[x]) x=fa[x];
// return x;
// }
// void Link(int x,int y){
// if(Get_fa(x)!=Get_fa(y)) Make_root(x),fa[x]=y;//Get_fa()有点慢啊
// }
void Link(int x,int y)
{
Make_root(x);
if(Find_root(y)!=x) fa[x]=y;//连的是轻边!不要加rson=y;
}
void Cut(int x,int y)
{
Make_root(x);
if(Find_root(y)==x&&fa[x]==y&&!rson)
fa[x]=son[y][0]=0, Update(y);
// if(Find_root(y)==x&&fa[y]==x&&!son[y][0])//若Find_root()中把根又转回去了
// fa[y]=rson=0, Update(x);
}
}
int main()
{
int n=read(),m=read();
for(int i=1; i<=n; ++i) LCT::val[i]=read();
int opt,x,y;
while(m--)
{
opt=read(),x=read(),y=read();
if(!opt) LCT::Split(x,y), printf("%d\n",LCT::sum[y]);
else if(opt==1) LCT::Link(x,y);
else if(opt==2) LCT::Cut(x,y);
else LCT::Splay(x), LCT::val[x]=y;/*sum[y]^=val[x]^y, val[x]=y*/ //这步在Split()(查询时)的Splay()中 最后还会Update()
}
return 0;
}
第二次(2018.4.5):
#include <cstdio>
#include <cctype>
#include <algorithm>
#define gc() getchar()
const int N=3e5+5;
inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
namespace LCT
{
#define lson son[x][0]
#define rson son[x][1]
int fa[N],son[N][2],sum[N],val[N],sk[N];
bool rev[N];
inline void Update(int x){
sum[x]=sum[lson]^sum[rson]^val[x];
}
inline bool n_root(int x){
return son[fa[x]][0]==x||son[fa[x]][1]==x;
}
inline void Rev(int x){
std::swap(lson,rson), rev[x]^=1;
}
inline void PushDown(int x){
if(rev[x]) Rev(lson),Rev(rson),rev[x]=0;
}
void Rotate(int x)
{
int a=fa[x],b=fa[a],l=son[a][1]==x,r=l^1;
if(n_root(a)) son[b][son[b][1]==a]=x;
if(son[x][r]) fa[son[x][r]]=a;
fa[a]=x, fa[x]=b, son[a][l]=son[x][r], son[x][r]=a;
Update(a);
}
void Splay(int x)
{
int t=1,a=x; sk[1]=x;
while(n_root(a)) sk[++t]=a=fa[a];
while(t) PushDown(sk[t--]);
while(n_root(x))
{
if(n_root(a=fa[x])) Rotate(son[a][1]==x^son[fa[a]][1]==a?x:a);
Rotate(x);
}
Update(x);
}
void Access(int x){
for(int pre=0; x; x=fa[pre=x])
Splay(x), rson=pre, Update(x);
}
void Make_root(int x){
Access(x), Splay(x), Rev(x);
}
void Split(int x,int y){
Make_root(x), Access(y), Splay(y);
}
int Find_root(int x)
{
Access(x), Splay(x);
while(lson) x=lson;
return x;
}
void Link(int x,int y)
{
Make_root(x);
if(Find_root(y)!=x) fa[x]=y;
}
void Cut(int x,int y)
{
Make_root(x);
if(Find_root(y)==x&&fa[x]==y&&!rson)
fa[x]=son[y][0]=0, Update(y);
}
}
using namespace LCT;
int main()
{
int n=read(),m=read(),opt,x,y;
for(int i=1; i<=n; ++i) val[i]=read();
while(m--)
switch(opt=read(),x=read(),y=read(),opt)
{
case 0: Split(x,y),printf("%d\n",sum[y]); break;
case 1: Link(x,y); break;
case 2: Cut(x,y); break;
case 3: Splay(x), val[x]=y; break;
}
return 0;
}
第三次(2018.6.28):竟然快了那么多,好像没什么太大变化啊。。
//592ms 3.76MB
#include <cstdio>
#include <cctype>
#include <algorithm>
//#define gc() getchar()
#define MAXIN 150000
#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
const int N=3e5+5;
char IN[MAXIN],*SS=IN,*TT=IN;
namespace LCT
{
#define lson son[x][0]
#define rson son[x][1]
int fa[N],son[N][2],val[N],sum[N],sk[N];
bool rev[N];
inline void Update(int x){
sum[x]=sum[lson]^sum[rson]^val[x];
}
inline void Rev(int x){
std::swap(lson,rson), rev[x]^=1;
}
inline void PushDown(int x){
if(rev[x]) Rev(lson), Rev(rson), rev[x]=0;
}
inline bool n_root(int x){
return son[fa[x]][0]==x||son[fa[x]][1]==x;
}
void Rotate(int x)
{
int a=fa[x],b=fa[a],l=son[a][1]==x,r=l^1;
if(n_root(a)) son[b][son[b][1]==a]=x;
if(son[x][r]) fa[son[x][r]]=a;
fa[x]=b, fa[a]=x, son[a][l]=son[x][r], son[x][r]=a;
Update(a);
}
void Splay(int x)
{
int a=x,t=1; sk[1]=x;
while(n_root(a)) sk[++t]=a=fa[a];
while(t) PushDown(sk[t--]);
while(n_root(x))
{
if(n_root(a=fa[x])) Rotate(son[a][1]==x^son[fa[a]][1]==a?x:a);
Rotate(x);
}
Update(x);
}
void Access(int x){
for(int pre=0; x; x=fa[pre=x])
Splay(x), rson=pre, Update(x);
}
void Make_root(int x){
Access(x), Splay(x), Rev(x);
}
void Split(int x,int y){
Make_root(x), Access(y), Splay(y);
}
int Find_root(int x)
{
Access(x), Splay(x);
while(lson) x=lson;
return x;
}
void Link(int x,int y)
{
Make_root(x);
if(Find_root(y)!=x) fa[x]=y;
}
void Cut(int x,int y)
{
Make_root(x);
if(Find_root(y)==x&&!rson&&fa[x]==y) son[y][0]=fa[x]=0, Update(y);
}
}
using namespace LCT;
inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
int main()
{
int n=read(), m=read();
for(int i=1; i<=n; ++i) val[i]=read();
int opt,x,y;
while(m--){
switch(opt=read(),x=read(),y=read(),opt){
case 0: Split(x,y), printf("%d\n",sum[y]); break;
case 1: Link(x,y); break;
case 2: Cut(x,y); break;
case 3: Splay(x), val[x]=y; break;
}
}
return 0;
}
19.4.5
//520ms 2984KB
#include <cstdio>
#include <cctype>
#include <algorithm>
#define gc() getchar()
#define MAXIN 300000
//#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
typedef long long LL;
const int N=3e5+5;
char IN[MAXIN],*SS=IN,*TT=IN;
struct LCT
{
#define ls son[x][0]
#define rs son[x][1]
int fa[N],son[N][2],sum[N],val[N],sk[N];
bool rev[N];
inline void Update(int x)
{
sum[x]=sum[ls]^sum[rs]^val[x];
}
inline bool n_root(int x)
{
return son[fa[x]][0]==x||son[fa[x]][1]==x;
}
inline void Rev(int x)
{
std::swap(ls,rs), rev[x]^=1;
}
inline void PushDown(int x)
{
if(rev[x]) Rev(ls), Rev(rs), rev[x]=0;
}
void Rotate(int x)
{
int a=fa[x],b=fa[a],l=son[a][1]==x,r=l^1;
if(n_root(a)) son[b][son[b][1]==a]=x;
if(son[x][r]) fa[son[x][r]]=a;
fa[x]=b, fa[a]=x, son[a][l]=son[x][r], son[x][r]=a;
Update(a);
}
void Splay(int x)
{
int t=1,a=x; sk[1]=a;
while(n_root(a)) sk[++t]=a=fa[a];
while(t) PushDown(sk[t--]);
while(n_root(x))
{
if(n_root(a=fa[x])) Rotate(son[a][0]==x^son[fa[a]][0]==a?x:a);
Rotate(x);
}
Update(x);
}
void Access(int x)
{
for(int pre=0; x; x=fa[pre=x])
Splay(x), rs=pre, Update(x);
}
void MakeRoot(int x)
{
Access(x), Splay(x), Rev(x);
}
void Split(int x,int y)
{
MakeRoot(x), Access(y), Splay(y);
}
int FindRoot(int x)
{
Access(x), Splay(x);
while(ls) x=ls;
return x;
}
void Link(int x,int y)
{
MakeRoot(x);
if(FindRoot(y)!=x) fa[x]=y;
}
void Cut(int x,int y)
{
MakeRoot(x);
if(FindRoot(y)==x&&fa[x]==y&&!rs) fa[x]=son[y][0]=0, Update(y);
}
}T;
inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-48,c=gc());
return now;
}
int main()
{
int n=read(),q=read();
for(int i=1; i<=n; ++i) T.val[i]=read();
for(int x,y; q--; )
switch(read())
{
case 0: x=read(),y=read(),T.Split(x,y),printf("%d\n",T.sum[y]); break;
case 1: x=read(),y=read(),T.Link(x,y); break;
case 2: x=read(),y=read(),T.Cut(x,y); break;
case 3: T.Splay(x=read()),T.val[x]=read(); break;
}
return 0;
}
洛谷.3690.[模板]Link Cut Tree(动态树)的更多相关文章
- LCT总结——概念篇+洛谷P3690[模板]Link Cut Tree(动态树)(LCT,Splay)
为了优化体验(其实是强迫症),蒟蒻把总结拆成了两篇,方便不同学习阶段的Dalao们切换. LCT总结--应用篇戳这里 概念.性质简述 首先介绍一下链剖分的概念(感谢laofu的讲课) 链剖分,是指一类 ...
- 洛谷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 ...
- 洛谷P2633 Count on a tree(主席树上树)
题目描述 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个询问的答案,初始为0,即第一个 ...
- 模板Link Cut Tree (动态树)
题目描述 给定N个点以及每个点的权值,要你处理接下来的M个操作.操作有4种.操作从0到3编号.点从1到N编号. 0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor和.保证x到y是联 ...
- 洛谷 P2633 Count on a tree 主席树
在一棵树上,我们要求点 $(u,v)$ 之间路径的第$k$大数. 对于点 $i$ ,建立 $i$ 到根节点的一棵前缀主席树. 简单容斥后不难得出结果为$sumv[u]+sumv[v]−sumv[l ...
- 洛谷P2633 Count on a tree 主席树
传送门:主席树 解题报告: 传送门! umm这题我还麻油开始做 所以 先瞎扯一波我的想法,如果错了我就当反面教材解释这种典型错误,对了我就不管了QwQ 就直接dfs,在dfs的过程中建树 然后就直接查 ...
随机推荐
- Pytorch 入门之Siamese网络
首次体验Pytorch,本文参考于:github and PyTorch 中文网人脸相似度对比 本文主要熟悉Pytorch大致流程,修改了读取数据部分.没有采用原作者的ImageFolder方法: ...
- ubuntu14.04 + cuda8.0 + cudnnv5 + caffe + py-faster-rcnn配置
经过几天的奋战终于配置好了如题所述的配置,现在把配置大体过程写下来供大家配置时参考(由于电脑硬件和系统的千差万别,实在不适合写详细的) (一切不声明配置环境的配置教程都是耍流氓) 环境: Inter集 ...
- MySQL基于LVM快照的备份恢复(临时)
目录1.数据库全备份2.准备LVM卷3.数据恢复到LVM卷4.基于LVM快照备份数据5.数据灾难恢复6.总结 写在前面:测试环境中已安装有mysql 5.5.36数据库,但数据目录没有存放在LVM卷, ...
- redis拾趣(客户端连接,keys命令,数据备份,缓存有效期等)
1.客户端连接 为了安全保护,redis支持绑定IP跟端口,这个通过conf配置文件中的bind跟port来设置. 绑定后登录client控制台时就需要写明ip(或者hostname)跟端口了,如: ...
- 随机森林学习-sklearn
随机森林的Python实现 (RandomForestClassifier) # -*- coding: utf- -*- """ RandomForestClassif ...
- JQ初学总结一
Jquery是最火的JavaScript库,大部分web开发都会用到就jquery,而作为初学者看了一些jq的用法总结自己的学习以增强自己的认知. 普通的javascript的缺点是:每种控件的操作方 ...
- Python-html css 盒模型
<!DOCTYPE html><html><head> <meta charset="UTF-8"> <title>ht ...
- 用jquery添加新元素很容易,面对jquery append 动态添加的元素事件on 不起作用我们该如何解决呢?
用jquery添加新元素很容易,面对jquery append 动态添加的元素事件on 不起作用我们该如何解决呢?on方法中要先找到原选择器(如例.info),再找到动态添加的选择器(如列.delet ...
- Java基础100 待续
1.待续 原创作者:DSHORE 作者主页:http://www.cnblogs.com/dshore123/ 原文出自:https://www.cnblogs.com/dshore123/p/107 ...
- VS2008/2005 MFC程序调试经验
我的VS2008不知道是有bug还是自己的问题,很多时候变量定义后CTRL+F5运行却没反应,一定要“生成解决方案”下才行? 1.没有可用于当前位置的源代码 将工具->选项->调试-> ...