动态树模板

Link Cut Tree:

#include<bits/stdc++.h>
#define L(x) T[(x)].son[0]
#define R(x) T[(x)].son[1]
#define fa(x) T[(x)].fa
using namespace std;
const int N=300050;
int stk[N];
int n,m;
struct Tree{
    int son[2],fa;
    int val,siz,Xor;
    bool tag;
}T[N];
bool isroot(int x){
    return (L(fa(x))==x||R(fa(x))==x)==0;
}
void pushup(int x){
    T[x].Xor=T[L(x)].Xor^T[R(x)].Xor^T[x].val;
    return;
}
void rev(int x){
    swap(L(x),R(x));
    T[x].tag^=1;
}
void pushdown(int x){
    if(T[x].tag){
        if(L(x))rev(L(x));
        if(R(x))rev(R(x));
        T[x].tag=0;
    }
}
bool identify(int x){
    return L(fa(x))==x?0:1;
}
void connect(int x,int fa,int son){
    fa(x)=fa;
    T[fa].son[son]=x;
}
//以下Splay与普通的Splay有若干处不同
void rotate(int x){
    int y=fa(x);
    int z=fa(y);
    int zson=identify(y);
    int yson=identify(x);
    int xson=T[x].son[yson^1];
    fa(x)=fa(y);//将x的父亲设成y的父亲:区别1
    if(!isroot(y))connect(x,z,zson);//判y,转的顺序不同:区别2
    connect(xson,y,yson);
    connect(y,x,yson^1);
    pushup(y);
    pushup(x);
    return ;
}
void splay(int x){//传一个参:区别3
    int tp=0,y=x;
    stk[++tp]=y;
    while(!isroot(y))stk[++tp]=y=fa(y);
    while(tp)pushdown(stk[tp--]);//存路径推标记:区别4
    while(!isroot(x)){
        int fa=fa(x);
        if(!isroot(fa)){//判y:区别5
            if(identify(x)!=identify(fa)){
                rotate(x);
            }else{
                rotate(fa);
            }
        }
        rotate(x);
    }//无换根:区别6
}
void access(int x){
    for(int y=0;x;y=x,x=fa(x)){
        splay(x);
        R(x)=y;
        pushup(x);
    }
}
void makeroot(int x){
    access(x);
    splay(x);
    rev(x);
}
int findroot(int x){
    access(x);
    splay(x);
    while(L(x)){
        pushdown(x);
        x=L(x);
    }
    splay(x);
    return x;
}
void split(int x,int y){
    makeroot(x);
    access(y);
    splay(y);
}
void link(int x,int y){
    makeroot(x);
    if(findroot(y)==x)return;
    fa(x)=y;
}
void cut(int x,int y){
    makeroot(x);
    if(findroot(y)!=x||fa(y)!=x||L(y))return;
    fa(y)=R(x)=0;
    pushup(x);
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%d",&T[i].val);
    }
    for(int i=1;i<=m;i++){
        int opt,x,y;
        scanf("%d%d%d",&opt,&x,&y);
        if(opt==0){
            split(x,y);
            printf("%d\n",T[y].Xor);
        }else if(opt==1){
            link(x,y);
        }else if(opt==2){
            cut(x,y);
        }else if(opt==3){
            splay(x);
            T[x].val=y;
        }
    }
} 

LCT

其他动态树待补

原文地址:https://www.cnblogs.com/passione-123456/p/12254028.html

时间: 2024-10-23 16:29:22

动态树模板的相关文章

HDU 2475 BOX 动态树 Link-Cut Tree 动态树模板

Box Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) [Problem Description] There are N boxes on the ground, which are labeled by numbers from 1 to N. The boxes are magical, the size of each one can be enlarged or r

bzoj2049-洞穴勘测(动态树lct模板题)

Description 辉辉热衷于洞穴勘测.某天,他按照地图来到了一片被标记为JSZX的洞穴群地区.经过初步勘测,辉辉发现这片区域由n个洞穴(分别编号为1到n)以及若干通道组成,并且每条通道连接了恰好两个洞穴.假如两个洞穴可以通过一条或者多条通道按一定顺序连接起来,那么这两个洞穴就是连通的,按顺序连接在一起的这些通道则被称之为这两个洞穴之间的一条路径.洞穴都十分坚固无法破坏,然而通道不太稳定,时常因为外界影响而发生改变,比如,根据有关仪器的监测结果,123号洞穴和127号洞穴之间有时会出现一条通

luoguP3690 【模板】Link Cut Tree (动态树)[LCT]

题目背景 动态树 题目描述 给定N个点以及每个点的权值,要你处理接下来的M个操作.操作有4种.操作从0到3编号.点从1到N编号. 0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor和.保证x到y是联通的. 1:后接两个整数(x,y),代表连接x到y,若x到Y已经联通则无需连接. 2:后接两个整数(x,y),代表删除边(x,y),不保证边(x,y)存在. 3:后接两个整数(x,y),代表将点X上的权值变成Y. 输入输出格式 输入格式: 第1行两个整数,分别为N和M,代表点数和操

LuoguP3690 【模板】Link Cut Tree (动态树) LCT模板

P3690 [模板]Link Cut Tree (动态树) 题目背景 动态树 题目描述 给定n个点以及每个点的权值,要你处理接下来的m个操作.操作有4种.操作从0到3编号.点从1到n编号. 0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor和.保证x到y是联通的. 1:后接两个整数(x,y),代表连接x到y,若x到y已经联通则无需连接. 2:后接两个整数(x,y),代表删除边(x,y),不保证边(x,y)存在. 3:后接两个整数(x,y),代表将点x上的权值变成y. 输入输出

P3690 【模板】Link Cut Tree (动态树)

P3690 [模板]Link Cut Tree (动态树) https://www.luogu.org/problemnew/show/P3690 分析: LCT模板 代码: 注意一下cut! 1 #include<cstdio> 2 #include<algorithm> 3 4 using namespace std; 5 6 const int N = 300100; 7 8 int val[N],fa[N],ch[N][2],rev[N],sum[N],st[N],top;

如何利用FineReport制作动态树报表

在对数据字段进行分类管理时,利用动态树折叠数据是一个很好的方法,也就是点击数据前面的加号才展开对应下面的数据,如下图.那这样的效果在制作报表时该如何实现呢? 下面以报表工具FineReport为例介绍. 思路: 通过将模版设置为组织树报表,然后通过设置树节点按钮,最好通过数据分析预览或者form表单预览即可查看效果. 步骤: 1.  初步建立模板 建立模板就相当于建立一个excel的sheet,只不过是cpt的形式.把相应的字段拖到单元格内. 2.  增加树节点按钮 通过设置树节点按钮来实现折叠

动态树分治

感受: 就是把分治结构变成树(并不需要真正建出,只需要记录父亲) 然后每个点维护子树到该点的信息,和子树到父亲点的信息 总体来说还是很模板的一个东西 题目大概分成两类: (1)树上黑白点染色,问一个点到所有黑点的距离和 这种就是原来真正的树结构上信息修改,那么一般就是将修改的点在分治树上所在的链每个点维护的信息加加减减. (2)另一种就是询问体现动态,比如距离某个点距离<=k的点的权值和 这种问题的突破点在于原树的信息是不改变的.所以我们可以在分治树上每个点维护一个vector数组来储存信息(有

树链剖分 BZOJ3589 动态树

3589: 动态树 Time Limit: 30 Sec  Memory Limit: 1024 MBSubmit: 543  Solved: 193[Submit][Status][Discuss] Description 别忘了这是一棵动态树, 每时每刻都是动态的. 小明要求你在这棵树上维护两种事件 事件0: 这棵树长出了一些果子, 即某个子树中的每个节点都会长出K个果子. 事件1: 小明希望你求出几条树枝上的果子数. 一条树枝其实就是一个从某个节点到根的路径的一段. 每次小明会选定一些树枝

hdu 5002 (动态树lct)

Tree Time Limit: 16000/8000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 920    Accepted Submission(s): 388 Problem Description You are given a tree with N nodes which are numbered by integers 1..N. Each node is a