(RE) luogu P3690 【模板】Link Cut Tree

二次联通门 : luogu P3690 【模板】Link Cut Tree

 

 

 

莫名RE第8个点。。。。如果有dalao帮忙查错的话万分感激

 

 

#include <cstdio>
#include <iostream>

#define Max 4000002

void read (int &now)
{
    now = 0;
    bool temp = false;
    register char word = getchar ();
    while (word < '0' || word > '9')
    {
        if (word == '-')
            temp = false;
        word = getchar ();
    }
    while (word >= '0' && word <= '9')
    {
        now = now * 10 + word - '0';
        word = getchar ();
    }
    if (temp)
        now = -now;
}

int N, M;

struct S_D 
{
    S_D *child[2];

    S_D *father;

    int key;
    int number;

    int Flandre;
    S_D (int __x) : number (__x)
    {
        child[0] = child[1] = NULL;

        father = NULL;
        key = __x;
        Flandre = 0;
    }

    inline void Updata ()
    {
        /*
        this->key ^= this->number;
        if (this->child[0])
            this->key ^= this->child[0]->key;
        if (this->child[1])
            this->key ^= this->child[1]->key;
        */
        if (this->child[0] != NULL && this->child[1] != NULL)
            this->key = this->child[0]->key ^ this->child[1]->key ^ this->number;
        else if (this->child[0] != NULL && this->child[1] == NULL)
            this->key = this->child[0]->key ^ this->number;
        else if (this->child[1] != NULL && this->child[0] == NULL)
            this->key = this->child[1]->key ^ this->number;
        else 
            this->key = this->number;
        //this->key = this->child[0]->key ^ this->number ^ this->child[1]->key;
        return ;
    }

    inline void Down ()
    {
        if (!this->Flandre)
            return ;
        std :: swap (this->child[0], this->child[1]);
        if (this->child[0])
            this->child[0]->Flandre ^= 1;
        if (this->child[1])
            this->child[1]->Flandre ^= 1;
        this->Flandre = 0;
    }

    inline int Get_Pos ()
    {
        return this->father->child[1] == this;
    }

    inline int Is_Root ()
    {
        return !(this->father) || (this->father->child[0] != this && this->father->child[1] != this);
    }


};

S_D *data[Max];
S_D *node[Max];

class L_T
{

    private :

        inline void Rotate (S_D *now)
        {
            int pos = now->Get_Pos () ^ 1;
            S_D *Father = now->father;
            Father->child[pos ^ 1] = now->child[pos];
            if (now->child[pos])
                now->child[pos]->father = Father;
            now->father = Father->father;
            if (!Father->Is_Root ())
                now->father->child[Father->Get_Pos ()] = now;
            Father->father = now;
            now->child[pos] = Father;
            Father->Updata ();
            now->Updata ();
        }

        inline void Splay (S_D *now)
        {
            int pos = 0;
            for (S_D *Father = now; ; Father = Father->father)
            {
                data[++pos] = Father;
                if (Father->Is_Root ())
                    break;
            }
            for (; pos >= 1; -- pos)
                data[pos]->Down ();
            for (; !now->Is_Root (); Rotate (now))
                if (!now->father->Is_Root ())
                    Rotate (now->Get_Pos () == now->father->Get_Pos () ? now->father : now);
            now->Updata ();
        }

        inline void Access (S_D *now)
        {
            for (S_D *Pre = NULL; now; Pre = now, now = now->father)
            {
                Splay (now);
                now->child[1] = Pre;
                now->Updata ();
            }
        }

        inline void Make_Root (S_D *now)
        {
            Access (now);
            Splay (now);
            now->Flandre ^= 1;
        }

    public :
        
        inline void Cut (S_D *x, S_D *y)
        {
            Make_Root (x);
            Access (y);
            Splay (y);
            x->father = y->child[0] = NULL;
            y->Updata ();
        }

        inline void Link (S_D *x, S_D *y)
        {
            Make_Root (x);
            x->father = y;
        }

        inline void Split (S_D *x, S_D *y)
        {
            Make_Root (x);
            Access (y);
            Splay (y);
        }

        inline bool Find (S_D *x, S_D *y)
        {
            while (x->child[0])
                x = x->child[0];
            while (y->child[0])
                y = y->child[0];
            return x == y;
        }
        
        inline int Query (int x, int y)
        {
            Split (node[x], node[y]);
            return node[y]->key;
        }

        inline void Change (int x, int y)
        {
            Access (node[x]);
            Splay (node[x]);
            node[x]->number = y;
            node[x]->Updata ();
        }
};

L_T Make;

int main (int argc, char *argv[])
{
    read (N);
    read (M);
    for (register int i = 0, x; i < N; i ++)
    {
        read (x);
        node[i] = new S_D (x);
    }
    int x, y, type;
    for (; M --; )
    {
        read (type);
        read (x);
        read (y);
        if (type == 0)
            printf ("%d\n", Make.Query (-- x, -- y));
        else if (type == 1)
        {
            x --;
            y --;
            if (!Make.Find (node[x], node[y]))
                Make.Link (node[x], node[y]);
        }
        else if (type == 2)
        {
            x --;
            y --;
            if (Make.Find (node[x], node[y]))
                Make.Cut (node[x], node[y]);
        }
        else
            Make.Change (-- x, y);
    }
    return 0;
}

 

posted @ 2017-06-09 09:26  ZlycerQan  阅读(245)  评论(0编辑  收藏  举报