zoukankan      html  css  js  c++  java
  • bzoj2002: [Hnoi2010]Bounce 弹飞绵羊

    【题意】

      给出n个点,每个点都会指向它后方的一个点,显然最后都指向一个不存在的点。把最后一个点当作根拎起来就是一棵树了。询问中,某一个点指向的点随时会变,显然就是要你支持动态改变树的结构。然后又会不时的询问一个点到根的距离。

    【题解】

      又是lct裸题,注意 维护splay的信息 和 传递标记。。。。。。

      其它的细节网上题解一大堆就不多述了。。。。。。

      一开始写lct真的好艰辛。。。

    【代码】

    #include <iostream>
    #include <cstdio>
    using namespace std;
    const int N=200005;
    int size[N],c[N][2],rev[N],fa[N],pre[N],a[N];
    int n,x,y,Q;
    void read(int &x)
    {
        x=0;char ch;int sign=1;
        do{ch=getchar();if(ch=='-')sign*=-1;}while (ch<'0' || ch>'9');
        do{x=x*10+ch-48;ch=getchar();}while (ch>='0' && ch<='9');
        x*=sign;
    }
    bool isroot(int x)
    {
        return c[fa[x]][0]!=x && c[fa[x]][1]!=x;
    }
    void up(int x)
    {
        size[x]=size[c[x][0]]+size[c[x][1]]+1;
    }
    void down(int x)
    { 
        if (rev[x])
        {
            rev[x]=0;        
            swap(c[x][0],c[x][1]);
            rev[c[x][0]]^=1,rev[c[x][1]]^=1;
        }
    }
    void rotate(int x)
    {    
        int y=fa[x],z=fa[y],l,r;    
        if (c[y][0]==x)    l=0;else l=1;r=1^l;
        if (!isroot(y))    if (c[z][0]==y)    c[z][0]=x;else c[z][1]=x;
        fa[x]=z;
         c[y][l]=c[x][r];fa[c[x][r]]=y;
        c[x][r]=y;fa[y]=x;
         up(y);up(x);
    } 
    void splay(int x)
    {
        int cnt=0,y=x,z;    
        while (!isroot(y))
        {
            a[++cnt]=y;
            y=fa[y];
        }
        a[++cnt]=y;
        while (cnt--)    down(a[cnt+1]);
        while (!isroot(x))
        {
            y=fa[x];z=fa[y];
            if (!isroot(y))
                if (c[y][0]==x ^ c[z][0]==y)
                    rotate(x);
                else rotate(y);
            rotate(x);
        }
    }
    void access(int x)
    {
        int t=0; 
        while (x)
        {
            splay(x);
            c[x][1]=t;
            t=x;x=fa[x];
        }
    }
    void mt(int x)
    {
        access(x);
        splay(x);
    }
    void make_root(int x)
    {
        mt(x);
         rev[x]^=1;
        down(x);
    }
    void link(int x,int y)
    {
        make_root(x);
        fa[x]=y;    
    }
    void cut(int x,int y)
    {
        make_root(x);
        mt(y);
        fa[x]=c[y][0]=0;
        up(y);
    }
    int solve(int x)
    {
        make_root(n+1);
        mt(x);
        return size[c[x][0]];
    }
    int main()
    {
        read(n);
        for (int i=1;i<=n;++i)
        {
            size[i]=1;
            read(pre[i]);
            pre[i]+=i;
            if (pre[i]>n)
                pre[i]=n+1;
            link(i,pre[i]);
        }
        read(Q);
        while (Q--)
        {
            read(x);
            if (x==1)
            {
                read(y);
                ++y;
                printf("%d\n",solve(y));
            }
            else
            {
                read(x);read(y);
                ++x;
                cut(x,pre[x]);
                y=x+y;
                if (y>n)    y=n+1;
                link(x,pre[x]=y);
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    ECharts之柱状图 饼状图 折线图
    Vue自定义指令(directive)
    HDU 1231 最大连续子序列
    POJ 2533 Longest Ordered Subsequence
    HDU 1163 Eddy's digital Roots
    HDU 2317 Nasty Hacks
    HDU 2571 命运
    HDU 4224 Enumeration?
    HDU 1257 最少拦截系统
    HDU 2740 Root of the Problem
  • 原文地址:https://www.cnblogs.com/Bleacher/p/7554134.html
Copyright © 2011-2022 走看看