QTREE5 Link-Cut Tree

\(Problem\ Link\)

Subject to the effect

You have been given a tree of n points, point numbers from 1 to n. Each point may have two colors: black or white. We define dist (a, b) is the number of edge points on a path to a point b.

Start all points are black.

Requirements for the following operations:

0 i i The color reversal points (black to white, white to black)

1 v interrogation minimum dist (u, v) of. must be a white point u (u and v may be the same), if v is clearly white spots, a value obtained by the query must be 0.

In particular, if as '1' when there is no operation tree white point, the output 1.

Ideological analysis

Dynamic point of divide and conquer approach this question see my summary

This dynamic point divide and conquer approach the question quite simple, but LCT practice on complex,Overall, however, the board still

We define \ (lmn [x], rmn [x] \) represent in \ (splay \) in \ (x \) sub-tree shallowest depth to reach the nearest point of the white point,

And it can reach a depth of the deepest point of the white point of the nearest

But also to open a heap or \ (multiset \) maintenance of a sudden the tree \ (lmn \) minimum.

This question was asked to the nearest point of the white point, there is no need to maintain a sub-tree information

Do not need the zipper, also do not split, makert, findrt so a lot of the operations

This time LCT is running fast, dynamic point than twice as fast as the partition \ (qwq \)

Code

/*
@Date    : 2019-09-10 17:14:38
@Author  : Adscn ([email protected])
@Link    : https://www.cnblogs.com/LLCSBlog
*/
#include<bits/stdc++.h>
using namespace std;
#define IL inline
#define RG register
#define gi getint()
#define gc getchar()
#define File(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout)
template<typename T>IL bool chkmax(T &x,const T &y){return x<y?x=y,1:0;}
template<typename T>IL bool chkmin(T &x,const T &y){return x>y?x=y,1:0;}
IL int getint()
{
    RG int xi=0;
    RG char ch=gc;
    bool f=0;
    while(!isdigit(ch))ch=='-'?f=1:f,ch=gc;
    while(isdigit(ch))xi=xi*10+ch-48,ch=gc;
    return f?-xi:xi;
}
template<typename T>
IL void pi(T k,char ch=0)
{
    if(k<0)k=-k,putchar('-');
    if(k>=10)pi(k/10,0);
    putchar(k%10+'0');
    if(ch)putchar(ch);
}
const int N=1e5+7;
const int inf=1e9;
int n;
namespace LCT{
    int fa[N],ch[N][2],lmn[N],rmn[N],siz[N],col[N];
    multiset<int>s[N];
    multiset<int>::iterator it;
    #define ls(x) (ch[x][0])
    #define rs(x) (ch[x][1])
    #define s(x,k) (ch[x][k])
    inline bool ws(int x,int p){return rs(p)==x;}
    inline bool nrt(int x){return ls(fa[x])==x||rs(fa[x])==x;}
    inline int fir(int x){return s[x].empty()?inf:*s[x].begin();}
    inline void pushup(int x){
        if(!x)return;
        siz[x]=siz[ls(x)]+siz[rs(x)]+1;
        lmn[x]=min(lmn[ls(x)],siz[ls(x)]+min(col[x]?0:inf,min(fir(x),lmn[rs(x)])+1));
        rmn[x]=min(rmn[rs(x)],siz[rs(x)]+min(col[x]?0:inf,min(fir(x),rmn[ls(x)])+1));
    }
    inline void rotate(int x){
        int p=fa[x],g=fa[p];
        int t=ws(x,p),w=s(x,!t);
        if(nrt(p))s(g,ws(p,g))=x;s(x,!t)=p;s(p,t)=w;
        if(w)fa[w]=p;fa[p]=x;fa[x]=g;
        pushup(p);
    }
    inline void Splay(int x){
        while(nrt(x))
        {
            int p=fa[x],g=fa[p];
            if(nrt(p))rotate(ws(x,p)^ws(p,g)?x:p);
            rotate(x);
        }
        pushup(x);
    }
    inline void access(int x){
        for(int y=0;x;x=fa[y=x])
        {
            Splay(x);
            s[x].insert(lmn[rs(x)]);
            if((it=s[x].lower_bound(lmn[y]))!=s[x].end())s[x].erase(it);
            rs(x)=y,pushup(x);
        }
    }
    inline void modify(int x){
        access(x),Splay(x);
        col[x]^=1;
        pushup(x);
    }
    inline int query(int x){
        access(x);Splay(x);
        return rmn[x]>n?-1:rmn[x];
    }
}
using namespace LCT;
struct edge{
    int v,nxt;
}e[N<<1|1];
int head[N],cnt;
inline void add(int u,int v){e[++cnt]=(edge){v,head[u]},head[u]=cnt;}
inline void init(){memset(head,cnt=-1,sizeof head);}
inline void dfs(int x,int p)
{
    for(int i=head[x],v;~i;i=e[i].nxt)
        if((v=e[i].v)^p)
            fa[v]=x,dfs(v,x);
}
int main(void)
{
    n=gi,lmn[0]=rmn[0]=inf;
    init();
    for(int i=1,u,v;i<n;++i)u=gi,v=gi,add(u,v),add(v,u);
    dfs(1,0);
    for(int i=1,m=gi;i<=m;++i)
    {
        int opt=gi,x=gi;
        if(opt^1)modify(x);
        else pi(query(x),'\n');
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/LLCSBlog/p/11511132.html