码迷,mamicode.com
首页 > 其他好文 > 详细

各种模板

时间:2018-03-30 00:12:35      阅读:144      评论:0      收藏:0      [点我收藏+]

标签:tree   --   mes   std   push   space   type   code   freopen   

各种模板

lct

#include<bits/stdc++.h>
using namespace std;
#define REP(i,st,ed) for(register int i=st,i##end=ed;i<=i##end;++i)
#define DREP(i,st,ed) for(register int i=st,i##end=ed;i>=i##end;--i)
typedef long long ll;
inline int read(){
    int x;
    char c;
    int f=1;
    while((c=getchar())!=‘-‘ && (c<‘0‘ || c>‘9‘));
    if(c==‘-‘) c=getchar(),f=-1;
    x=c^‘0‘;
    while((c=getchar())>=‘0‘ && c<=‘9‘) x=(x<<1)+(x<<3)+(c^‘0‘);
    return x*f;
}
inline ll readll(){
    ll x;
    char c;
    ll f=1;
    while((c=getchar())!=‘-‘ && (c<‘0‘ || c>‘9‘));
    if(c==‘-‘) c=getchar(),f=-1;
    x=c^‘0‘;
    while((c=getchar())>=‘0‘ && c<=‘9‘) x=(x<<1ll)+(x<<3ll)+(c^‘0‘);
    return x*f;
}
const int maxn=3e5+10;
#define ls(x) (ch[x][0])
#define rs(x) (ch[x][1])
#define isr(x) (rs(fa[x])==x)
int stk[maxn],Top;
struct Link_cut_tree{
    int sum[maxn],ch[maxn][2],fa[maxn],rev[maxn],val[maxn];
    inline bool isroot(int x){
        return rs(fa[x])!=x && ls(fa[x])!=x;
    }
    inline void push_up(int x){
        sum[x]=sum[ls(x)]^sum[rs(x)]^val[x];
    }
    inline void push_down(int x){
        if(rev[x]){
            int l=ls(x),r=rs(x);
            if(l) swap(ch[l][0],ch[l][1]),rev[l]^=1;
            if(r) swap(ch[r][0],ch[r][1]),rev[r]^=1;
            rev[x]=0;
        }
    }
    inline void rotate(int x){
        int f=fa[x],ff=fa[f],u=isr(x);
        ch[fa[ch[x][u^1]]=f][u]=ch[x][u^1];
        fa[x]=ff;if(!isroot(f)) ch[ff][isr(f)]=x;
        ch[fa[f]=x][u^1]=f;
        push_up(f);
    }
    inline void splay(int x){
        stk[Top=1]=x;
        for(int i=x;!isroot(i);i=fa[i]) stk[++Top]=fa[i];
        DREP(i,Top,1) push_down(stk[i]);
        for(;!isroot(x);rotate(x))
            if(!isroot(fa[x])) rotate((isr(fa[x])^isr(x))?x:fa[x]);
        push_up(x);
    }
    inline void access(int x){
        for(int i=0;x;x=fa[i=x]) splay(x),ch[x][1]=i,push_up(x);
    }
    inline void makeroot(int x){
        access(x),splay(x),rev[x]^=1,swap(ch[x][0],ch[x][1]);
    }
    inline int findroot(int x){
        access(x),splay(x);
        while(ch[x][0]) push_down(x),x=ch[x][0];
        splay(x);return x;
    }
    inline void split(int x,int y){
        makeroot(x),access(y),splay(y);
    }
    inline bool link(int x,int y){
        makeroot(x);
        if(findroot(y)==x) return 0;
        fa[x]=y;return 1;
    }
    inline void cut(int x,int y){
        split(x,y);
        if(ch[y][0]==x)  fa[x]=ch[y][0]=0;
    }
}lct;
int main(){
#ifndef ONLINE_JUDGE
    freopen("lct.in","r",stdin);
    freopen("lct.out","w",stdout);
#endif
    int n=read(),q=read();
    REP(i,1,n) lct.val[i]=lct.sum[i]=read();
    while(q--){
        int ty=read(),x=read(),y=read();
        if(ty==0) lct.split(x,y),printf("%d\n",lct.sum[y]);
        else if(ty==1) lct.link(x,y);
        else if(ty==2) lct.cut(x,y);
        else lct.access(x),lct.splay(x),lct.val[x]=y,lct.push_up(x);
    }
    return 0;
}

各种模板

标签:tree   --   mes   std   push   space   type   code   freopen   

原文地址:https://www.cnblogs.com/zhou888/p/8673126.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!