• bzoj2002(lct模板)


    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    const int maxn=200010;
    struct node{
        int ls,rs,fa,is_root;
    }tr[maxn];
    int n,m,siz[maxn],k[maxn];
    void update(int x){
        siz[x]=1;
        if(tr[x].ls)siz[x]+=siz[tr[x].ls];
        if(tr[x].rs)siz[x]+=siz[tr[x].rs];
    }
    void rx(int x){
        int y=tr[x].fa,z=tr[y].fa;
        tr[y].ls=tr[x].rs;
        if(tr[x].rs)tr[tr[x].rs].fa=y;
        tr[x].rs=y;tr[y].fa=x;
        tr[x].fa=z;
        if(z&&!tr[y].is_root){//注意这句判断,辅助树之间的边是单向的;
            if(tr[z].ls==y)tr[z].ls=x;else tr[z].rs=x;
        }
        if(tr[y].is_root)tr[x].is_root=1,tr[y].is_root=0;
        update(y);update(x);
    }
    void lx(int x){
        int y=tr[x].fa,z=tr[y].fa;
        tr[y].rs=tr[x].ls;
        if(tr[x].ls)tr[tr[x].ls].fa=y;
        tr[x].ls=y;tr[y].fa=x;
        tr[x].fa=z;
        if(z&&!tr[y].is_root){
            if(tr[z].ls==y)tr[z].ls=x;else tr[z].rs=x;
        }
        if(tr[y].is_root)tr[x].is_root=1,tr[y].is_root=0;
        update(y);update(x);
    }
    void splay(int x){
        while(!tr[x].is_root){
            int y=tr[x].fa,z=tr[y].fa;
            if(tr[y].is_root){if(tr[y].ls==x)rx(x);else lx(x);}
            else{
                if(tr[z].ls==y&&tr[y].ls==x){rx(y);rx(x);}
                else if(tr[z].ls==y&&tr[y].rs==x){lx(x);rx(x);}
                else if(tr[z].rs==y&&tr[y].ls==x){rx(x);lx(x);}
                else{lx(y);lx(x);}
            }
        }
    }
    void ace(int x){
        int y=0;
        do{
            splay(x);
            tr[tr[x].rs].is_root=1;
            tr[tr[x].rs=y].is_root=0;
            update(x);
            x=tr[y=x].fa;
        }while(x);
    }
    void link(int u,int v){//虽然说是link,但也包含和原来的断开然后和新的连上的两个过程
        if(v>n)v=0;
        ace(u);splay(u);
        tr[tr[u].ls].is_root=1;
        tr[tr[u].ls].fa=0;tr[u].ls=0;
        tr[u].fa=v;update(u);
    }
    int query(int x){
        ace(x);splay(x);
        return siz[tr[x].ls]+1;
    }
    int main(){
        scanf("%d",&n);
        for(int i=1;i<=n;++i){
            tr[i].is_root=siz[i]=1;
            tr[i].fa=tr[i].ls=tr[i].rs=0;
        }
        for(int i=1;i<=n;++i){
            scanf("%d",&k[i]);
            link(i,i+k[i]);
        }
        scanf("%d",&m);
        int op,pos,cha;
        for(int i=1;i<=m;++i){
            scanf("%d%d",&op,&pos);
            if(op==1)printf("%d
    ",query(pos+1));
            else{
                scanf("%d",&cha);
                link(pos+1,pos+cha+1);
            }
        }
        //system("pause");
        return 0;
    }
  • 相关阅读:
    [NOIP2008] 传纸条
    [NOIP2006] 能量项链
    [poj2393] Yogurt factory
    [poj3069] Saruman's Army
    [NOIP2011] 观光公交
    [NOIP2010] 关押罪犯
    [洛谷2744] 量取牛奶
    [poj3281] Dining
    关于几类STL容器的swap复杂度问题
    折半法
  • 原文地址:https://www.cnblogs.com/dibaotianxing/p/8340985.html
Copyright © 2020-2023  润新知