【动态树】hdu4897

两种操作,第一种一条路径的边的颜色取反,第二种将一半在这条路径中的边的颜色取反,询问一条路径黑边的数量。

每条边上再添一个代表点表示这条边的颜色,那么第一种操作就可以直接把要操作的链取出来,再打个标记,第二种操作可以给每个点加一个标记,表示这个点的虚边连出去的儿子会要变一次颜色,然后再直接把lca的父亲节点变个颜色,可以看到,当access的时候只有有限条边会从虚变实或者从实变虚,此时用父亲节点的标记修改一下即可。

需要注意的是access的时候实变虚或者虚变实都要考虑到修改,然后还有两种操作在边界的直接修改操作。

#include 
#include 
#include 
#include 
#include 
using namespace std;
int l[300000],r[300000],rt[300000],sum[300000],cl[300000],cl2[300000],bj[300000],sw[300000],sw2[300000];
int size[300000];
int tail[300000],next[1000000],sora[1000000];
int n,ss,m;
inline void updata(int x)
{
    if (!x) return ;
    sum[x]=sum[l[x]]+sum[r[x]]+cl[x]*bj[x];
    size[x]=size[l[x]]+size[r[x]]+bj[x];
}
inline void swap(int x)
{
    if (!x) return ;
    sw[x]^=1;
    cl[x]^=1;
    sum[x]=size[x]-sum[x];
}
inline void swap2(int x)
{
    if (!x) return ;
    sw2[x]^=1;
    cl2[x]^=1;
}
inline void pushdown(int x)
{
    if (!x) return ;
    if (sw[x]) {
        if (l[x]) swap(l[x]);
        if (r[x]) swap(r[x]);
        sw[x]=0;
    }
    if (sw2[x]) {
        if (l[x]) swap2(l[x]);
        if (r[x]) swap2(r[x]);
        sw2[x]=0;
    }
}
inline void right(int x)
{
    int y=rt[x],z=rt[y];
    l[y]=r[x],rt[r[x]]=y;
    r[x]=y,rt[y]=x;
    if (l[z]==y) l[z]=x;else if (r[z]==y) r[z]=x;
    rt[x]=z;
    updata(y);
}
inline void left(int x)
{
    int y=rt[x],z=rt[y];
    r[y]=l[x],rt[l[x]]=y;
    l[x]=y,rt[y]=x;
    if (l[z]==y) l[z]=x;else if (r[z]==y) r[z]=x;
    rt[x]=z;
    updata(y);
}
inline void splay(int x)
{
    if (!x) return ;
    pushdown(x);
    for (int y,z;l[rt[x]]==x || r[rt[x]]==x;) {
        y=rt[x],z=rt[y];
        if (l[z]==y || r[z]==y) pushdown(z);
        pushdown(y),pushdown(x);
        if (l[y]==x) {
            if (l[z]==y) right(y);
            right(x);
        }
        else if (r[y]==x) {
            if (r[z]==y) left(y);
            left(x);
        }
    }
    updata(x);
}
inline void access(int x)
{
    if (!x) return ;
    bool flag=(x==2);
    splay(x);
    int tmp;
    for (tmp=l[x];r[tmp];tmp=r[tmp]) ;
    l[x]=0,updata(x);
    if (tmp) splay(tmp),cl[tmp]^=(cl2[x]*(!bj[x])),updata(tmp);
    for (;rt[x];) {
        int y=rt[x];
        splay(y);
        int tmp;
        for (tmp=x;r[tmp];tmp=r[tmp]) ;
        splay(tmp);
        cl[tmp]^=(cl2[y]*(!bj[y])),updata(tmp);
        tmp=l[y];
        for (;r[tmp];tmp=r[tmp]) ;
//        if (flag) cout<


你可能感兴趣的:(hdu,数据结构)