bzoj2843

就是很裸的lct,犯的错误已经在代码中标出。

(学校食堂今天的八宝粥是糊的发火

(bzoj 3091需要这个代码的对照)

2015.9.11:

注意修改数据时,要考虑对于现在的结构造成的影响,所以某个节点的数据修改前,考虑需不需要access()(感觉怎么这么像需求管理中的需求变更?敲打好像暴露专业了)

//感觉只要任何时刻任何两点之间都只有一条路的话,好像可以用lct
#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
#define N 30010

struct node{
    node *fa;//这里一开始不要赋值
    node *ch[2];
    int val;
    int root;
    int sum;
    int valnum;
    int rev;

    void init(int tempval,int tempvalnum){
        val=tempval;
        valnum=tempvalnum;
        sum=valnum;
        root=val;
        ch[0]=NULL;
        ch[1]=NULL;
        fa=NULL;
        rev=0;
    }

    bool isroot(){
        /*if(!(fa->ch[1])){
            printf("wo shi da hao ren");
        }
        printf("wo shi da hao ren");*///调错:不明白这里为什么只要涉及到fa->ch[0]和fa-ch[1]就会出错

        /*if(fa==NULL){
            printf("wo shi da hao ren");
        }*///调错:fa要么等于NULL,要么不等于NULL,为什么这里无论等于还是不等于都不输出呢?

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

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

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

        return;
    }

    void go(){
        if(!isroot()){//这里是isroot,不是fa->isroot(),这里的错会在isroot处停止执行
            fa->go();
        }
        push_down();

        return;
    }

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

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

    void push_up(){
        sum=valnum;

        if(ch[0]){
            root=ch[0]->root;
            sum+=ch[0]->sum;
        }
        else{
            root=val;
        }

        if(ch[1]){
            sum+=ch[1]->sum;
        }
    }

    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();//这里没回来printf("wo shi da hao ren");

        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();//调错:这里没回来printf("wo shi da hao ren");
            p->setedge(1,q);
            p->push_up();
        }
        splay();

        return;
    }

    void make_root(){
        access();//调错:这里是access不是rev^=1,这里没回来printf("wo shi da hao ren");
        fswitch();
    }

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

        return;
    }

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

        return;
    }

    bool islink(node *another){
        make_root();//调错:make_root()函数改了以后,是这里就没回来
        another->access();//调错:这里没回来printf("wo shi da hao ren");
        if(another->root==this->val){
            return true;
        }
        else{
            return false;
        }
    }

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

        return another->sum;
    }

    void change(int tempvalnum){
        access();
        valnum=tempvalnum;//这句没写,所以wr了
        sum=tempvalnum;
        if(ch[0]){
            sum+=ch[0]->sum;
        }

        return;
    }
};

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

int main(){
    int n;
    int m;
    int a,b;
    char op[20];

    while(scanf("%d",&n)!=EOF){
        for(int i=1;i<=n;i++){
            scanf("%d",&a);
            tree[i]=&(pool[i]);
            tree[i]->init(i,a);
        }
        scanf("%d",&m);
        for(int i=0;i<m;i++){
            scanf("%s%d%d",op,&a,&b);
            if(op[0]=='b'){
                if(tree[a]->islink(tree[b])){
                    printf("no\n");
                }
                else{
                    printf("yes\n");
                    tree[a]->link(tree[b]);
                }
            }
            else if(op[0]=='p'){
                tree[a]->change(b);
            }
            else{

                if(tree[a]->islink(tree[b])){
                    printf("%d\n",tree[a]->query(tree[b]));
                }
                else{
                    printf("impossible\n");
                }
            }
        }
    }

    return 0;
}

posted @ 2015-09-01 15:18  buzhidaohahaha  阅读(117)  评论(0编辑  收藏  举报