1. 程式人生 > >洛谷P3690 【模板】Link Cut Tree (動態樹)

洛谷P3690 【模板】Link Cut Tree (動態樹)

不開o2優化就要TLE,不知道為啥。

//#include <bits/stdc++.h>
#pragma GCC optimize(2)
#include<stdio.h>
#include<string.h>
#include<string>
#include<math.h>
#include<algorithm>
#include<iostream>
#include<queue>
#include<vector>
#include<stack>
#include<map>
#include<set>
#include<stdlib.h>
#include<time.h>
#include <iomanip>
#define lowbit(x) (x&(-x))
#define inf  0x7fffffff
#define linf 0x7fffffffffffffff
#define mem(x,y) memset(x,y,sizeof(x))
#define fup(i,x,y) for(int i=(x);i<=(y);i++)
#define fdn(i,x,y) for(int i=(x);i>=(y);i--)
#define sp(x) setprecision(x)
#define sd(n) scanf("%d",&n)
#define sdd(n,m) scanf("%d%d",&n,&m)
#define sddd(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define sld(n) scanf("%lld",&n)
#define sldd(n,m) scanf("%lld%lld",&n,&m)
#define slddd(n,m,k) scanf("%lld%lld%lld",&n,&m,&k)
#define sf(n) scanf("%lf",&n)
#define sff(n,m) scanf("%lf%lf",&n,&m)
#define sfff(n,m,k) scanf("%lf%lf%lf",&n,&m,&k)
#define sc(n) scanf("%s",n)
#define pf(x) printf("%d\n",x)
#define pfl(x) printf("%lld\n",x)
#define pff(x) printf("%lf\n",x)
#define debug printf("!!\n");
#define N 300005
#define M 4000009
#define pi acos(-1)
#define eps 1e-2
//cout.setf(ios::fixed);
//freopen("out.txt","w",stdout);// freopen("in.txt","r",stdin);
using namespace std;
typedef long long  ll;
typedef double db;
const int mod=1e9+7;
struct node
{
    public:int fa,son[2],shu,sum;
    bool Reverse;
    void ini()
    {
    fa=son[0]=son[1]=Reverse=0;
    }
}t[N];
int n,m,fa[N];
inline bool is_root(int x)
{
    int fa=t[x].fa;
    return (t[fa].son[0]!=x&&t[fa].son[1]!=x);
}
inline void pushreverse(int x)
{
    if(!x) return ;
    swap(t[x].son[0],t[x].son[1]);
    t[x].Reverse^=1;
}
inline void update(int x)
{
    t[x].sum=t[x].shu;
    int l=t[x].son[0],r=t[x].son[1];
    if(l) t[x].sum^=t[l].sum;
    if(r) t[x].sum^=t[r].sum;
}
inline void pushdown(int x)
{
    if(t[x].Reverse)
    {
        pushreverse(t[x].son[0]);
        pushreverse(t[x].son[1]);
        t[x].Reverse=false;
    }
}
inline int get(int x)
{
    return x==t[t[x].fa].son[1];
}
inline void Rotate(int x)
{
    if(is_root(x)) return;
    int k=get(x),fa=t[x].fa,fafa=t[fa].fa;
 
    if(!is_root(fa)) t[fafa].son[fa==t[fafa].son[1]]=x;
    t[fa].son[k]=t[x].son[k^1];
 
    if(t[x].son[k^1]) t[t[x].son[k^1]].fa=fa;
    t[x].son[k^1]=fa;
    t[fa].fa=x;
    t[x].fa=fafa;
    update(x);
    update(fa);
}
inline void push(int x)
{
    if(!is_root(x)) push(t[x].fa);
    pushdown(x);
}
inline void splay(int x)
{
    push(x);
    for(int fa;!is_root(x);Rotate(x))
    {
        fa=t[x].fa;
     //   cout<<x<<' '<<fa<<' '<<is_root(fa)<<' '<<t[0].son[0]<<' '<<t[0].son[1]<<endl;
        if(!is_root(fa)) Rotate(get(x)==get(fa)?fa:x);
    }
}
inline void access(int x)
{
    int y=0;
    do
    {
        splay(x);
    //    t[t[x].son[1]].is_root=true;
        t[x].son[1]=y;
    //    t[y].fa=x;
        update(x);
        x=t[y=x].fa;
    }while(x);
}
inline void mroot(int x)
{
    access(x);
    splay(x);
    pushreverse(x);
 //   update(x);
}
inline int findroot(int x)
{
    while(t[x].fa) x=t[x].fa;
    return x;
}
inline void link(int u,int v)
{
    mroot(u);
    if(findroot(v)!=u)t[u].fa=v;
  //  update(u);
}
inline void cut(int u,int v)
{
    mroot(u);
    access(v);
    splay(v);
    if(t[v].son[0]!=u) return ;
    t[u].fa=t[v].son[0]=0;
    update(v);
}
 
int main()
{
    int m;
    sdd(n,m);
  //  fup(i,1,n)
  //      t[i].ini();
    fup(i,1,n)
    {
        sd(t[i].shu);
        t[i].sum=t[i].shu;
    }
    while(m--)
    {
        int f, x,y;
        sddd(f,x,y);
        if(!f)
        {
            mroot(x);
            access(y);
            splay(y);
            update(y);
            pf(t[y].sum);
        }
        else if(f==1)
        {
            link(x,y);
        }
        else if(f==2)
        {
           cut(x,y);
        }
        else
        {
            splay(x);
            t[x].shu=y;
            update(x);
        }
    }
}