BZOJ3282, luoguP3690. [Template] Link Cut Tree (Dynamic Tree)

problem

Background of topic

Dynamic tree

Title Description

Given n n n n points and the weights of each point, you are asked to process the next m operations. There are four operations. Operations are numbered from 0 to 3. Points from 1 to n are numbered.

0: followed by two integers (x, y), representing the xor and sum of the weights of the points on the path from X to y. Make sure that x to y is connected.

1: Two integers (x, y) follow, representing connections from X to y. If x to y is already connected, no connection is required.

2: Next two integers (x, y), representing deleted edges (x, y), do not guarantee the existence of edges (x, y).

3: The next two integers (x, y) represent the change of the weight on point x to y.

Input and Output Format

Input format:
The first row contains two integers, n and m, representing points and operands.

Lines 2 to n+1, each line has an integer, which is in [1, 10 ^ 9], representing the weight of each point.

Lines n+2 to n+m+1, each with three integers representing the type of operation and the amount of operation required.

Output format:
For each 0 operation, you have to output the xor and sum of the dot weights on the path from x to y.

Input and Output Samples

Input Sample #1: Replication
3 3
1
2
3
1 1 2
0 1 2
0 1 1
Output Sample #1: Replication
3
1
Explain

Data range: 1 Leq N,M Leq 3 cdot {10}^ 51 < N,M < 3 10
5

analysis

  • Or LCT board topic is almost the board in the world I have

  • Just pay attention to two points.

  • The two points of link, cut link and cut are not necessarily connected. Judge them with judgejudge.

  • There is also a [i]. sum= (a [i]. val) XOR (a [t [i] [0]]. sum) XOR (a [t [i] [1]]]]. sum) a [i]. sum= (a [i]. val) XOR (a [t [i] [0]. sum) XOR (a [t [i] [0] [sum] [1]).

  • So simple

code

#include<bits/stdc++.h>
#define MAXN 300001

using namespace std;

int t[MAXN][2];
int b[MAXN],fa[MAXN],pf[MAXN],st[MAXN];
char s[10];
int n,m;

struct node 
{
    int val,sum,mx,size;
    bool rev;
}a[MAXN];

int read()
{
    int x=0,f=1;
    char ch=getchar();
    while (ch<'0' || '9'<ch)
    {
        if (ch=='-')f=-1;
        ch=getchar();   
    }
    while ('0'<=ch && ch<='9')
    {
        x=x*10+ch-'0';
        ch=getchar();
    }
    return x*f;
}

void reverse(int x) 
{
    if(x)
    {
        a[x].rev^=1;
        swap(t[x][0],t[x][1]);
    }
}

void down(int x) 
{
    if (a[x].rev) 
    {
        reverse(t[x][0]),reverse(t[x][1]);
        a[x].rev=0;
    }
}

void update(int x) 
{
    if (x)
    {
        a[x].size=a[t[x][0]].size+a[t[x][1]].size+1;
        a[x].sum=a[x].val^a[t[x][0]].sum^a[t[x][1]].sum;
    } 
}

void downdata(int x) 
{
    st[0]=0;
    while (x)st[++st[0]]=x,x=fa[x];
    while (st[0])down(st[st[0]--]);
}

int lr(int x)
{
    return t[fa[x]][1]==x;
}

void rotate(int x) 
{
    int y=fa[x],k=lr(x);
    t[y][k]=t[x][!k];

    if (t[x][!k])fa[t[x][!k]]=y;
    fa[x]=fa[y];

    if (fa[y])t[fa[y]][lr(y)]=x;    
    t[x][!k]=y;

    fa[y]=x,pf[x]=pf[y];
    update(y),update(x);
}

void splay(int x, int y) 
{
    downdata(x);
    while (fa[x]!=y)
    {
        if (fa[fa[x]]!=y)
        {
            if (lr(x)==lr(fa[x]))rotate(fa[x]); 
            else rotate(x);
        } 
        rotate(x);
    }
}

void access(int x) 
{
    for (int y=0;x;update(x),y=x,x=pf[x])
    {
        splay(x,0);
        fa[t[x][1]]=0;
        pf[t[x][1]]=x;
        t[x][1]=y;
        fa[y]=x;
        pf[y]=0;
    }
}

void makeroot(int x) 
{
    access(x); 
    splay(x,0); 
    reverse(x);
}

int getroot(int x)
{
    while (fa[x])x=fa[x];
    return x;
}

bool judge(int x,int y)
{
    makeroot(x);
    access(y);
    splay(x,0);
    return getroot(y)==x;
}

void link(int x,int y) 
{
    if (!judge(x,y))
    {
        makeroot(x); 
        pf[x]=y;
    }
}

void cut(int x,int y) 
{
    if (judge(x,y))
    {
        makeroot(x); 
        access(y);
        splay(x,0);
        t[x][1]=fa[y]=pf[y]=0;
        update(x);
    }
}

int main()
{
    //freopen("readin.txt","r",stdin);
    n=read(),m=read();
    a[0].val=a[0].sum=0;
    for (int i=1;i<=n;i++)
    {
        splay(i,0);
        a[i].val=read();
        update(i);
    }
    while (m--)
    {
        int z=read(),x=read(),y=read();
        if (z==0)
        {
            makeroot(y);
            access(x);
            splay(x,0);
            printf("%d\n",a[x].sum);
        }
        else if (z==1)link(x,y);
        else if (z==2)cut(x,y);
        else 
        {
            splay(x,0);
            a[x].val=y;
            update(x);
        }
    }
}

Posted by robdavies on Thu, 13 Dec 2018 14:45:24 -0800