zoukankan      html  css  js  c++  java
  • Luogu 3203 BZOJ 2002——弹飞绵羊

    Luogu 3203  BZOJ 2002——弹飞绵羊

    题意概括

    给定一个序列,有N个装置,绵羊在不同

    其实就是个裸LCT。

    从i能跳到i+k即可以理解为i到i+k之间有一条连边

    修改操作即断边然后连边。

    在查询时只需要把要出发的点成为原树的根,然后访问n+1,把n+1splay到根,然后结果就在n+1的子树中了。

    #include<cstdio>
    #include<algorithm>
    #define maxn 200100
    using namespace std;
    struct TREE{
        int c[2],sum,fa,rev;
    }tree[maxn];
    int stack[maxn],n,a[maxn];
    int read(){
        int w=0;char c=getchar();
        while(c<'0'||c>'9') c=getchar();
        while(c>='0'&&c<='9') w=w*10+c-48,c=getchar();
        return w;
    }
    inline void update(int x){
        tree[x].sum=tree[tree[x].c[0]].sum+tree[tree[x].c[1]].sum+1;
    }
    inline void pushdown(int x){
        if(!tree[x].rev) return;
        int l=tree[x].c[0],r=tree[x].c[1];
        if(l) tree[l].rev^=1;
        if(r) tree[r].rev^=1;
        swap(tree[x].c[0],tree[x].c[1]);
        tree[x].rev^=1;
    }
    bool isroot(int x){
        return tree[tree[x].fa].c[0]!=x&&tree[tree[x].fa].c[1]!=x;
    }
    bool get(int x) {
    return x==tree[tree[x].fa].c[1];}
    void rotate(int x){
        int f=tree[x].fa,ff=tree[tree[x].fa].fa,opt=get(x);
        tree[f].c[opt]=tree[x].c[opt^1];
        tree[tree[x].c[opt^1]].fa=f; 
        if(!isroot(f)) tree[ff].c[get(f)]=x;
        tree[x].fa=ff;tree[f].fa=x;
        tree[x].c[opt^1]=f;
        update(f);update(x);
    }
    void splay(int x){
        int top=0,tmp=x;stack[++top]=x;
        while(!isroot(tmp))stack[++top]=tree[tmp].fa,tmp=tree[tmp].fa;
        while(top)pushdown(stack[top]),top--;
        while(!isroot(x)){
            rotate(x); 
        }
    } 
    void access(int x){
        int son=0;
        while(x){
            splay(x);tree[x].c[1]=son;
            update(x);son=x;x=tree[x].fa;
        }
    }
    void makeroot(int x){
        access(x);splay(x);tree[x].rev^=1;
    }
    void link(int x,int y){
        makeroot(x);tree[x].fa=y;
        splay(x);
    }
    void cut(int x,int y){
        makeroot(x);access(y);
        splay(y);tree[y].c[0]=tree[x].fa=0;
    }
    int query(int x,int y){
        makeroot(x);access(y);splay(y);
        return tree[y].sum;
    }
    int getfa(int x){
        access(x);splay(x);
        while(tree[x].c[0]){
            pushdown(x);x=tree[x].c[0];
            splay(x);
        } 
        return x;
    }
    void change(int x,int y){
        makeroot(x);
    //    tree[x].val=y;
        update(x);
    }
    void answer(int i){
        makeroot(i); access(n+1); splay(n+1);
    //    printf("1");
        printf("%d
    ",tree[n+1].sum-1);
    }
    int main(){
        int x,i,opt,m,k;
        n=read();
        for(i=1;i<=n;i++){
            x=a[i]=read();
            if(i+x<=n) link(i,i+x);
            else link(i,n+1);
        }
        m=read();
        for(i=1;i<=m;i++){
            opt=read();x=read()+1; 
            if(opt==1) answer(x);
            else {k=read();if(a[x]+x<=n)cut(x,a[x]+x);else cut(x,n+1);
            if(x+k<=n)link(x,x+k);else link(x,n+1);a[x]=k;}
        }
    }
    弹飞绵羊
  • 相关阅读:
    静静的看twittervision
    MSSQL中的随机函数
    紧张非封闭式开发中
    be my friend
    这个五一
    检讨
    SilverLight,有多少人关心呢?
    并查集模板题P3367 【模板】并查集
    并查集简单介绍
    约数之和模板题
  • 原文地址:https://www.cnblogs.com/Fish-/p/8270617.html
Copyright © 2011-2022 走看看