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
  • 相关阅读:
    ChemDraw绘制DNA结构的技巧
    几何画板中该如何插入公式
    MathType可以编辑带圈乘号吗
    几何画板是这样构造扇形内部的
    Chem 3D软件可以改变背景吗
    移动端上下滑动事件之--坑爹的touch.js
    在HTML5中如何提高网站前端性能
    git入门
    php 路由实现
    vb 定时执行php程序
  • 原文地址:https://www.cnblogs.com/Bleacher/p/7554134.html
Copyright © 2011-2022 走看看