zoukankan      html  css  js  c++  java
  • bzoj 2002

    LCT板子题...

    看到题目中的操作很显然是从$i$向$i+k_{i}$连一条边,每次修改就是删除原来的边再加入一条新的边嘛

    然后考虑查询:对于被弹飞的部分,我们统一新建一个节点$n+1$,把所有越过边界的部分指向这个节点即可

    然后在查询的时候只需要拎出查询节点到$n+1$节点的树链,统计其大小即可

    注意节点编号读入时加一

    贴代码:

    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <stack>
    using namespace std;
    int siz[200005];
    int ch[200005][2];
    int fl[200005],f[200005];
    int to[200005];
    int n,m;
    void update(int x)
    {
        siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+1;
    }
    bool be_root(int x)
    {
        if(ch[f[x]][0]==x||ch[f[x]][1]==x)return 0;
        return 1;
    }
    void pushdown(int x)
    {
        if(fl[x])
        {
            swap(ch[ch[x][0]][0],ch[ch[x][0]][1]);
            swap(ch[ch[x][1]][0],ch[ch[x][1]][1]);
            fl[ch[x][0]]^=1,fl[ch[x][1]]^=1;
            fl[x]=0;
        }
    }
    void repush(int x)
    {
        if(!be_root(x))repush(f[x]);
        pushdown(x);
    }
    void rotate(int x)
    {
        int y=f[x],z=f[y],k=(ch[y][1]==x);
        if(!be_root(y))ch[z][ch[z][1]==y]=x;
        f[x]=z;
        ch[y][k]=ch[x][!k],f[ch[x][!k]]=y;
        ch[x][!k]=y,f[y]=x;
        update(y),update(x);
    }
    void splay(int x)
    {
        repush(x);
        while(!be_root(x))
        {
            int y=f[x],z=f[y];
            if(!be_root(y))
            {
                if((ch[y][1]==x)^(ch[z][1]==y))rotate(x);
                else rotate(y);
            }
            rotate(x);
        }
        update(x);
    }
    void access(int x)
    {
        int y=0;
        while(x)
        {
            splay(x);
            ch[x][1]=y;
            update(x);
            y=x,x=f[x];
        }
    }
    int get_root(int x)
    {
        access(x),splay(x);
        while(ch[x][0])pushdown(x),x=ch[x][0];
        return x;
    }
    void make_root(int x)
    {
        access(x),splay(x);
        swap(ch[x][0],ch[x][1]),fl[x]^=1;
    }
    void link(int x,int y)
    {
        make_root(x);
        if(get_root(y)!=x)f[x]=y;
    }
    void cut(int x,int y)
    {
        make_root(y);
        if(get_root(x)==y&&f[y]==x&&!ch[y][1])ch[x][0]=f[y]=0,update(x);
    }
    inline int read()
    {
        int f=1,x=0;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    int main()
    {
        n=read();
        for(int i=1;i<=n;i++)to[i]=read(),link(i,min(i+to[i],n+1));
        m=read();
        while(m--)
        {
            int typ=read();
            if(typ==1)
            {
                int x=read()+1;
                make_root(x),access(n+1),splay(n+1);
                printf("%d
    ",siz[n+1]-1);
            }else
            {
                int x=read()+1,y=read();
                cut(x,min(x+to[x],n+1));
                to[x]=y;
                link(x,min(x+to[x],n+1));
            }
        }
        return 0;
    }
  • 相关阅读:
    基于GDAL库,读取.grd文件(以海洋地形数据为例)Java版
    基于GDAL库,读取.nc文件(以海洋表温数据为例)C++版
    基于UDP传输协议局域网文件接收软件设计 Java版
    基于Oracle数据库登陆界面及功能实现 Java版
    ORM中的Model与DDD中的DomainModel
    探讨DDD中角色权限与DCI的使用
    哈工大软件构造 复习
    python列表的基本用法
    matlab简单的超越方程求解近似值
    MATLAB一些常用的function
  • 原文地址:https://www.cnblogs.com/zhangleo/p/11162473.html
Copyright © 2011-2022 走看看