zoukankan      html  css  js  c++  java
  • bzoj3510 首都

    题目描述:给你n个点和m个操作:

    1.链接两个点。

    2.查询某点所在树的重心。

    3.查询所有树重心的异或和。

    其实就是lct维护虚子树,链接时新重心一定在原来的两重心连线上,相当于splay查询区间第k大值(区间中点)。

    代码:

    #include<cstdio>
    #include<algorithm>
    #define N 100050
    int n,m;
    int fa[N],rt[N],ch[N][2],s[N],sx[N],sr;
    bool res[N];
    bool is_not_root(int x)
    {
        return (ch[fa[x]][0]==x)|(ch[fa[x]][1]==x);
    }
    void update(int x)
    {
        s[x]=s[ch[x][0]]+s[ch[x][1]]+sx[x]+1;
    }
    void reser(int x)
    {
        res[x]^=1;
        std::swap(ch[x][0],ch[x][1]);
    }
    void pushdown(int x)
    {
        if(res[x])
        {
            res[x]=0;
            reser(ch[x][0]);
            reser(ch[x][1]);
        }
    }
    void down(int x)
    {
        if(is_not_root(x))down(fa[x]);
        pushdown(x);
    }
    void rotate(int x)
    {
        int y = fa[x],k = (ch[y][1]==x);
        if(is_not_root(y))ch[fa[y]][ch[fa[y]][1]==y]=x;
        fa[x]=fa[y];
        ch[y][k]=ch[x][!k],fa[ch[x][!k]]=y;
        ch[x][!k]=y,fa[y]=x;
        update(y),update(x);
    }
    void splay(int x)
    {
        down(x);
        while(is_not_root(x))
        {
            int y = fa[x],z=fa[y];
            if(is_not_root(y))
                ((ch[y][1]==x)^(ch[z][1]==y))?rotate(x):rotate(y);
            rotate(x);
        }
    }
    void access(int x)
    {
        int y = 0;
        while(x)
        {
            splay(x);
            sx[x]+=s[ch[x][1]];
            sx[x]-=s[y];
            ch[x][1]=y;
            update(x);
            y=x,x=fa[x];
        }
    }
    void mtr(int x)
    {
        access(x);
        splay(x);
        reser(x);
    }
    void split(int x,int y)
    {
        mtr(x);
        access(y);
        splay(y);
    }
    void link(int x,int y)
    {
        split(x,y);
        fa[x]=y;
        sx[y]+=s[x];
        update(y);
    }
    int findrt(int x)
    {
        if(rt[x]==x)return x;
        return rt[x]=findrt(rt[x]);
    }
    int getfa(int x)
    {
        int goal = s[x]>>1,tip = (s[x]&1);
        int ls = 0,rs = 0,ret = 0x7fffffff,vl,vr;
        while(x)
        {
            pushdown(x);
            vl = s[ch[x][0]]+ls;
            vr = s[ch[x][1]]+rs;
            if(vl<=goal&&vr<=goal)
            {
                if(tip){ret=x;break;}
                else if(ret>x)ret=x;
            }
            if(vl>vr)
            {
                rs += s[ch[x][1]]+sx[x]+1;
                x = ch[x][0];
            }else
            {
                ls += s[ch[x][0]]+sx[x]+1;
                x = ch[x][1];
            }
        }
        splay(ret);
        return ret;
    }
    int main()
    {
        scanf("%d%d",&n,&m); 
        for(int i=1;i<=n;i++)
        {
            s[i]=1;
            sr^=i;
            rt[i]=i;
        }
        int u,v;
        char sc[10];
        for(int i=1;i<=m;i++)
        {
            scanf("%s",sc);
            if(sc[0]=='X')
            {
                printf("%d
    ",sr);
            }else if(sc[0]=='Q')
            {
                scanf("%d",&u);
                printf("%d
    ",findrt(u));
            }else
            {
                scanf("%d%d",&u,&v);
                link(u,v);
                u=findrt(u),v=findrt(v);
                split(u,v);//v=rt
                int r = getfa(v);
                sr = sr^u^v^r;
                rt[u] = rt[v] = rt[r] = r;
            }
        }
        return 0;
    }
  • 相关阅读:
    C++ Builder XE2随意学习 (12) > DevExpress Dock拖动框架实现
    C++ Builder XE2随意学习 (14) > 窗口透明处理
    C++ Builder XE2随意学习(9) > 安装实录
    C++ Builder XE2随意学习 (13) > Gdiplus
    C++ Builder XE2随意学习 (10) > AlphaControls控件使用初探
    ASP.NET 4.0 视频教程
    C++ Builder XE2随意学习 (11) > DevExpress Ribbon界面效果
    C++ Builder XE2随意学习 (7) > RAD Studio XE2 – Setting it up for a Mac
    C++ Builder XE2随意学习(8) > 快速入门教程
    jQuery实现倒计时效果
  • 原文地址:https://www.cnblogs.com/LiGuanlin1124/p/9649796.html
Copyright © 2011-2022 走看看