LCT模板坑点总结

#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;
const int MAXN=100005;
int n,m;
struct LCT {
    int fa[MAXN],val[MAXN],rev[MAXN],ch[MAXN][2],sum[MAXN],tot;
    int stk[MAXN],tp;
    void up(int x) {
        sum[x]=sum[ch[x][0]]^sum[ch[x][1]]^val[x];
    }
    void push_rev(int x) {
        rev[x]^=1;
        swap(ch[x][0],ch[x][1]);
    }
    void down(int x) {
        if(rev[x]) {
            rev[x]=0;
            push_rev(ch[x][0]);
            push_rev(ch[x][1]);
        }
    }
    int get(int x) {
        return ch[fa[x]][1]==x;
    }
    bool isroot(int x) {
        return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;
    }
    void rotate(int x) {
        int f1=fa[x],f2=fa[f1],id=get(x);
        ch[f1][id]=ch[x][id^1]; fa[ch[f1][id]]=f1;
        if(!isroot(f1)) ch[f2][get(f1)]=x; fa[x]=f2; //!!!!!
        ch[x][id^1]=f1; fa[f1]=x;
        up(f1);
    }
    void splay(int x) {
        tp=0;
        int y=x;
        stk[++tp]=y; //!!!!!
        while(!isroot(y)) stk[++tp]=y=fa[y];
        while(tp) down(stk[tp--]);
        while(!isroot(x)) { //!!!!!
            int f1=fa[x],f2=fa[f1];
            if(!isroot(f1)) {
                if(get(x)==get(f1)) rotate(f1);
                else rotate(x);
            }
            rotate(x);
        }
        up(x);
    }
    void access(int x) {
        for(int y=0;x;y=x,x=fa[x])
            splay(x),ch[x][1]=y,up(x);
    }
    void makeroot(int x) {
        access(x);
        splay(x);
        push_rev(x);
    }
    int findroot(int x) {
        access(x); splay(x);
        while(ch[x][0]) x=ch[x][0];
        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) fa[x]=y;
    }
    void cut(int x,int y) {
        makeroot(x);
        if(findroot(y)==x&&fa[y]==x&&!ch[y][0]) { //!!!!!
            fa[y]=ch[x][1]=0;
            up(x);
        }
    }
}tr;
int main() {
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++) scanf("%d",&tr.val[i]);
    for(int i=1;i<=m;i++) {
        int opt,x,y;
        scanf("%d%d%d",&opt,&x,&y);
        switch(opt) {
            case 0: tr.split(x,y); printf("%d\n",tr.sum[y]); break;
            case 1: tr.link(x,y); break;
            case 2: tr.cut(x,y); break;
            case 3: tr.makeroot(x); tr.val[x]=y; tr.up(x); break;
        }
    }
    return 0;
}

原文地址:https://www.cnblogs.com/Gkeng/p/12003058.html

时间: 2024-10-12 02:10:40

LCT模板坑点总结的相关文章

2014鞍山网络预选赛1006(LCT模板题)hdu5002

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

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. 输入输出

LCT 填坑系列

清华冬令营 T1用了LCT 这个东西以前有写过 然而并不熟练 发现没了板子根本就不会写 只能填一填坑辣 BZOJ 2843 LCT 1 #include <bits/stdc++.h> 2 #define N 30010 3 #define ls c[x][0] 4 #define rs c[x][1] 5 using namespace std; 6 7 inline int read() 8 { 9 int x=0,f=1; char ch=getchar(); 10 while(ch&l

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

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

[自用]模板坑待填

Kruskal 最小生成树 重要程度:★★★★☆ 熟练程度:★★★★☆ 代码比较短,还是好理解,就是打的少了点 #include<iostream> #include<cstdio> #include<algorithm> using namespace std; int n,m; struct save { int from;int to;int quan; }cun[10000]; bool aaa(const save &s,const save &

【模板整合】LCT模板

原题树的统计Count LCT动态维护树信息.比链剖好写但是速度真的没太有优势- #include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #define LL long long #define MAXN 50010 #define MAXINT 0x7fffffff using namespace std; struct

【BZOJ2049,2631,3282,1180】LCT模板四连A

好吧我并不想讲LCT 只是贴4个代码~ [BZOJ2049][Sdoi2008]Cave 洞穴勘测 #include <cstdio> #include <cstring> #include <iostream> #define isr(A) (s[s[A].fa].ch[0]!=A&&s[s[A].fa].ch[1]!=A) using namespace std; const int maxn=10010; int n,m; struct NODE

lct模板

1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #define N 450005 6 #define M 300005 7 #define lc(x) ch[x][0] 8 #define rc(x) ch[x][1] 9 #define inf 0x3f3f3f3f 10 using namespace std; 11 int f[N];

洞穴勘测——LCT模板

改了4小时,我果然还是太弱了-- #include<bits/stdc++.h> using namespace std; const int maxx=1e4+5; int c[maxx][2],fa[maxx],Rev[maxx]; int get(int x){ if(c[fa[x]][1]==x)return 1; if(c[fa[x]][0]==x)return 0; return -1; }void rot(int x){ int f=fa[x],ff=fa[f],l=get(x)