zoukankan      html  css  js  c++  java
  • BZOJ 3282 Tree

    LCT裸题。

    x到y的路径上的点是makeroot(x),access(y)后的splay上的所有节点。

    注意很多个不保证。

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cstring>
    #define maxv 500500
    using namespace std;
    int n,q,w[maxv],tree[maxv][5],fath[maxv],v[maxv],rev[maxv];
    int type,x,y,stack[maxv],cnt;
    bool isroot(int x)
    {
        return (tree[fath[x]][1]!=x)&&(tree[fath[x]][2]!=x);
    }
    void pushdown(int x)
    {
        int ls=tree[x][1],rs=tree[x][2];
        if (rev[x])
        {
            rev[x]=0;rev[ls]^=1;rev[rs]^=1;
            swap(tree[x][1],tree[x][2]);
        }
    }
    void pushup(int x)
    {
        int ls=tree[x][1],rs=tree[x][2];
        v[x]=v[ls]^v[rs]^w[x];
    }
    void rotate(int x)
    {
        int y=fath[x],z=fath[y],l,r;
        if (tree[y][1]==x) l=1;else l=2;
        r=3-l;
        if (!isroot(y))
        {
            if (tree[z][1]==y) tree[z][1]=x;
            else tree[z][2]=x;
        }
        fath[x]=z;fath[y]=x;fath[tree[x][r]]=y;
        tree[y][l]=tree[x][r];tree[x][r]=y;
        pushup(y);pushup(x);
    }
    void splay(int x)
    {
        cnt=0;stack[++cnt]=x;
        for(int i=x;!isroot(i);i=fath[i])
            stack[++cnt]=fath[i];
        for (int i=cnt;i>=1;i--)
            pushdown(stack[i]);
        while (!isroot(x))
        {
            int y=fath[x],z=fath[y];
            if (!isroot(y))
            {
                if ((tree[y][1]==x)^(tree[z][1]==y)) rotate(x);
                else rotate(y);
            }
            rotate(x);
        }
    }
    void access(int x)
    {
        int regis=0;
        while (x)
        {
            splay(x);
            tree[x][2]=regis;
            regis=x;pushup(x);x=fath[x];
        }
    }
    void makeroot(int x)
    {
        access(x);
        splay(x);
        rev[x]^=1;
    }
    void split(int x,int y)
    {
        makeroot(x);access(y);splay(y);
        printf("%d
    ",v[y]);
    }
    int find(int x)
    {
        access(x);
        splay(x);
        int now=x;
        while (tree[now][1]) now=tree[now][1];
        return now;
    }
    void link(int x,int y)
    {
        makeroot(x);fath[x]=y;
    }
    void cut(int x,int y)
    {
        makeroot(x);access(y);
        splay(y);tree[y][1]=0;fath[x]=0;
    }
    void work0()
    {
        scanf("%d%d",&x,&y);
        split(x,y);
    }
    void work1()
    {
        scanf("%d%d",&x,&y);
        if (find(x)!=find(y)) link(x,y);
    }
    void work2()
    {
        scanf("%d%d",&x,&y);
        if (find(x)==find(y)) cut(x,y);
    }
    void work3()
    {
        scanf("%d%d",&x,&y);
        access(x);splay(x);w[x]=y;pushup(x);
    }
    int main()
    {
        scanf("%d%d",&n,&q);
        for (int i=1;i<=n;i++)
        {
            scanf("%d",&w[i]);
        }
        for (int i=1;i<=q;i++)
        {
            scanf("%d",&type);
            if (type==0) work0();
            else if (type==1) work1();
            else if (type==2) work2();
            else work3();
        }
        return 0;
    }
  • 相关阅读:
    ListIterator
    List与set
    iterator取集合元素
    我眼中的AI
    集合的共性方法
    集合转数组
    打开与关闭eclipse的自动补全功能
    Mr_matcher的细节1
    nodelet的应用
    nodelet的理解
  • 原文地址:https://www.cnblogs.com/ziliuziliu/p/5444102.html
Copyright © 2011-2022 走看看