bzoj3553: [Shoi2014]三叉神经树 树链剖分

来源:互联网 发布:易订货源码下载 编辑:程序博客网 时间:2024/04/28 22:49

此题的完成,代表近期的树链剖分就告一段落,全力进入联赛复习。

省选day2 的第二题,当时只是写了裸的bfs,TE到家了。

4个月后学长偶然的一句:树链剖分也可以,考试的时候就vfk一个人想到了。。。

如今看来,vfk走出考场说“今天三个题都是暴力”,是正确的。

由于每次改变根节点,那么这个到1的路径上的点才有可能更新。

当根节点由0变为1时,只会对上一个节点是1的点有影响,如果不是1直接更新这个点就可以了。

反过来 一个根节点由1变为0时,只会对上一个节点是2的产生影响。

val记录这个点有几个值为1的儿子

可是线段树如何介入呢。

这就是vfk的那句暴力了。

如果这个点由0变为了1,那么他所有的父节点中连续的只有一个子节点为1 即val[ i ]==1的点的值都会变为1;

如果这个点由1变为了0,那么他所有的父节点中连续的只有两个子节点为1 即val[ i ]==2的点的值都会变为0;

(建议自己画个图看一下)

这里就把O(n)的修改降为了O(logn);

所以线段树只需维护区间左右连续的值的长度即可。

每一次update后都要判断有没有到根节点。


/**************************************************************    Problem: 3553    User: xujiahe    Language: C++    Result: Accepted    Time:23080 ms    Memory:175812 kb****************************************************************/ #include <iostream>#include <cstring>#include <cstdio>#include <algorithm>#include <cmath>#include <queue>using namespace std;#define maxn 2100000#define ll long long#define lson rt<<1,l,m#define rson rt<<1|1,m+1,r#define  ss printf("orz\n")inline int readint(){    int flag=0;    char ch = getchar();    int data = 0;    while (ch < '0' || ch > '9')    {        if(ch=='-') flag=1;        ch = getchar();    }    do    {        data = data*10 + ch-'0';        ch = getchar();    }while (ch >= '0' && ch <= '9');        if(flag) data=-data;    return data;}int fa[maxn],siz[maxn],top[maxn],w[maxn],son[maxn],dep[maxn],id,dy[maxn],nn,val2[maxn];struct node{    int v,next;}g[maxn];int num,n,first[maxn],val[maxn];int tree[maxn],col[maxn],lcol[maxn],rcol[maxn],lmax[maxn],rmax[maxn],sum[maxn];void build(int a,int b){    num++;    g[num].v=b;    g[num].next=first[a];    first[a]=num;}void dfs(int now){    if (now>nn) return;    int v,ceng;    int maxv=0,flag=0,tmp=0;    siz[now]=1;    for(int i=first[now];i;i=g[i].next)    {        v=g[i].v;        if(v==fa[now]) continue;        dfs(v);        dep[v]=dep[now]+1;        fa[v]=now;        val2[now]+=val[v];        if(val[v])        {            tmp++;        }        siz[now]+=siz[v];        if(siz[v]>maxv)        {            maxv=siz[v];            flag=v;        }    }    son[now]=flag;    if(tmp>1)        val[now]=1;    else        val[now]=0;}void getid(int now,int root){    if(now>nn) return;    w[now]=++id;    top[now]=root;    dy[id]=now;    if(son[now]) getid(son[now],top[now]);    for(int i=first[now]; i; i=g[i].next)    {        if(g[i].v!=son[now]&&g[i].v!=fa[now])        {            getid(g[i].v,g[i].v);        }    }}void pushdown(int rt){    if(col[rt]!=0)    {        col[rt<<1]+=col[rt];        col[rt<<1|1]+=col[rt];        lcol[rt<<1]+=col[rt];        rcol[rt<<1]+=col[rt];        lcol[rt<<1|1]+=col[rt];        rcol[rt<<1|1]+=col[rt];        col[rt]=0;    }}void pushup(int rt,int len){    lmax[rt]=lmax[rt<<1];    if(lmax[rt<<1]==(len-(len>>1))&&rcol[rt<<1]==lcol[rt<<1|1])    {        lmax[rt]+=lmax[rt<<1|1];    }    rmax[rt]=rmax[rt<<1|1];    if(rmax[rt<<1|1]==(len>>1)&&rcol[rt<<1]==lcol[rt<<1|1])    {        rmax[rt]+=rmax[rt<<1];    }         lcol[rt]=lcol[rt<<1];    rcol[rt]=rcol[rt<<1|1];}void buildt(int rt,int l,int r){    int m=(l+r)>>1;    if(l==r)    {        lmax[rt]=rmax[rt]=1;        lcol[rt]=rcol[rt]=val2[dy[l]];        return ;    }    buildt(lson);    buildt(rson);    pushup(rt,r-l+1);}int getval(int rt,int l,int r,int x){    int m=(l+r)>>1;    if(l==r)    {        return lcol[rt];    }    pushdown(rt);    if(x<=m)    {        return getval(lson,x);    }    else    {        return getval(rson,x);    } }int getlen(int rt,int l,int r,int x,int y){    if(x==l&&y==r)    {        return rmax[rt];    }    pushdown(rt);    int tmp=0;    int m=(l+r)>>1;    if(y<=m)    {        return getlen(lson,x,y);    }    else if(x>m)    {        return getlen(rson,x,y);    }    else    {        tmp=getlen(rson,m+1,y);        if (tmp<y-m||rcol[rt<<1]!=lcol[rt<<1|1]) return tmp;        else return tmp+getlen(lson,x,m);    }}void update(int rt,int l,int r,int x,int y,int c){    if(x==l&&y==r)    {        lcol[rt]+=c;        rcol[rt]+=c;        col[rt]+=c;        return;    }    pushdown(rt);    int m=(l+r)>>1;    if(y<=m)    {        update(lson,x,y,c);    }    else if(x>m)    {        update(rson,x,y,c);    }    else    {        update(lson,x,m,c);        update(rson,m+1,y,c);    }    pushup(rt,r-l+1);}void getans(int x,int op){    int xx=x;    if(op==1)    {        while(x)        {            if(getval(1,1,n,w[x])!=1)            {                update(1,1,n,w[x],w[x],1);                break;            }            int len=getlen(1,1,n,w[top[x]],w[x]);            update(1,1,n,max(w[x]-len+1,1),w[x],1);            if (max(w[x]-len+1,1)!=1 && len!=w[x]-w[top[x]]+1)            {                update(1,1,n,w[fa[dy[w[x]-len+1]]],w[fa[dy[w[x]-len+1]]],1);            }            if (len!=w[x]-w[top[x]]+1) break;            x=fa[top[x]];        }    }    else    {        while(x)        {            if(getval(1,1,n,w[x])!=2)            {                update(1,1,n,w[x],w[x],-1);                break;            }            int len=getlen(1,1,n,w[top[x]],w[x]);            update(1,1,n,max(w[x]-len+1,1),w[x],-1);            if (max(w[x]-len+1,1)!=1 && len!=w[x]-w[top[x]]+1)            {                update(1,1,n,w[fa[dy[w[x]-len+1]]],w[fa[dy[w[x]-len+1]]],-1);            }            if (len!=w[x]-w[top[x]]+1) break;            x=fa[top[x]];        }    }}int main(){    char str[20];    int a,b,c,m;    n=readint();    nn=n;    for(int i=1;i<=n;i++)    {        a=readint();        b=readint();        c=readint();        build(i,a);        build(i,b);        build(i,c);    }    for(int i=1;i<=2*n+1;i++)    {        val[i+n]=readint();    }    n=n*3+1;    fa[1]=0;    dfs(1);    getid(1,1);    int x,y,z;    n=nn;    memset(col,0,sizeof(col));    buildt(1,1,n);    m=readint();    while(m--)    {       x=readint();       if(val[x]==0)       {           val[x]^=1;           getans(fa[x],1);       }       else       {           val[x]^=1;           getans(fa[x],2);       }       printf("%d\n",getval(1,1,n,1)>1);    }    return 0;}/*32 3 45 6 78 9 100 0 0 0 1 1 1544568////////////10011*/



0 0