bzoj2002

应该认真读题,虽然这道题编号从0开始,但是因为梅毒提(没读题,觉得错的挺有创意的,就只注释一下吧,留个念),理所当然的想成了从1开始,结果一直re。

(两个牛肉一个韭菜鸡蛋包子不知道怎么就变成了两个韭菜鸡蛋和一个牛肉大哭

2015.9.11:

今天发现这道题其实也可以用有向树去做,其实有向树,和无向树之间的区别,就是如果是无向树,就可以随意定原树的根节点,可以随意更换根节点,因此,就行某些操作时,必须要进行make_root()操作,以此来保证根节点是要求的那个,而有向树,因为根节点是固定的,因此,能肯定原树的根节点是什么,就不需要进行make_root()操作了。至于具体某道题用什么树合适,就要看题意了,无向树可以转换成有向树,如果能保存原树的根节点,那么有向树,也可以变成无向树,只要每次进行相关的操作时,进行个保存的那个根节点 -> make_root(),就行了。

#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
#define N 300010

struct node{
    node *fa;
    node *ch[2];
    int rev;
    int siz;

    void init(){
        fa=NULL;
        ch[0]=NULL;
        ch[1]=NULL;
        rev=0;
        siz=1;

        return;
    }

    void fswitch(){
        rev^=1;
        swap(ch[0],ch[1]);
        return;
    }

    void push_down(){
        if(rev){
            if(ch[0]){
                ch[0]->fswitch();
            }
            if(ch[1]){
                ch[1]->fswitch();
            }
            rev=0;
        }

        return;
    }

    bool isroot(){
        return fa==NULL||(fa->ch[0]!=this&&fa->ch[1]!=this);
    }

    void go(){
        if(!isroot()){
            fa->go();
        }
        push_down();

        return;
    }

    int dir(){
        return fa->ch[1]==this?1:0;
    }

    void setedge(int d,node *tempch){
        ch[d]=tempch;
        if(tempch){
            tempch->fa=this;
        }

        return;
    }

    void push_up(){
        siz=1;
        if(ch[0]){
            siz+=ch[0]->siz;
        }
        if(ch[1]){
            siz+=ch[1]->siz;
        }

        return;
    }

    void rot(){
        int d=dir();
        node *tempfafa=fa->fa;

        if(!(fa->isroot())){
            tempfafa->ch[fa->dir()]=this;
        }
        fa->setedge(d,ch[!d]);
        setedge(!d,fa);
        fa=tempfafa;
        ch[!d]->push_up();

        return;
    }

    void splay(){
        go();

        while(!isroot()){
            if(!(fa->isroot())){
                dir()==fa->dir()?fa->rot():rot();
            }
            rot();
        }
        push_up();

        return;
    }

    void access(){
        for(node *p=this,*q=NULL;p!=NULL;q=p,p=p->fa){
            p->splay();
            p->setedge(1,q);
            p->push_up();
        }
        splay();

        return;
    }

    void make_root(){
        access();
        fswitch();
    }

    void cut(node *another){
        make_root();
        another->access();
        another->ch[0]->fa=NULL;
        another->ch[0]=NULL;
        another->push_up();
    }

    void link(node *another){
        another->make_root();
        another->fa=this;

        return;
    }

    int query(node *another){
        make_root();
        another->access();

        return another->siz;
    }
};

node *tree[N],pool[N];
int tx[N];

int main(){
    int n;
    int m;
    int a,b,x;
    int op;

    while(scanf("%d",&n)!=EOF){
        for(int i=0;i<=n;i++){
            pool[i].init();
            tree[i]=&(pool[i]);
        }
        for(int i=0;i<n;i++){
            scanf("%d",&x);
            if(i+x>=n){
                tree[i]->link(tree[n]);
                tx[i]=n;
            }
            else{
                tree[i]->link(tree[i+x]);
                tx[i]=i+x;
            }
        }

        scanf("%d",&m);
        for(int i=1;i<=m;i++){
            scanf("%d",&op);
            if(op==1){
                scanf("%d",&a);
                printf("%d\n",(tree[a]->query(tree[n]))-1);
            }
            else if(op==2){
                scanf("%d%d",&a,&b);
                tree[a]->cut(tree[tx[a]]);
                if(a+b>n){
                    tree[a]->link(tree[n]);
                    tx[a]=n;
                }
                else{
                    tree[a]->link(tree[a+b]);
                    tx[a]=a+b;
                }
            }
        }
    }

    return 0;
}


posted @ 2015-08-24 09:12  buzhidaohahaha  阅读(89)  评论(0编辑  收藏