首页 > 代码库 > BZOJ2819 Nim 树链剖分

BZOJ2819 Nim 树链剖分

题意:给定一个树,维护:1、u到v是否有必胜策略  2、将u的权值修改为w

题解:BFS版的树链剖分

技术分享
#include <cstdio>#include <cstring>#include <cstdlib>#include <iostream>#include <algorithm>using namespace std;const int MAXN=500000+2;struct HASH{    int u;    HASH *next;    HASH(){}    HASH(int _u,HASH *_next):u(_u),next(_next){}}mem[MAXN*2];struct NODE{    int u,v,c,f,son,mark,depth,belong;    HASH *child;}node[MAXN],*q[MAXN];typedef struct TREE{    int s,l,r;    TREE *lchild,*rchild;    TREE(){}    TREE(int _l,int _r):l(_l),r(_r),lchild(0),rchild(0){}} *ROOT;ROOT root;int N,Q,cnt,mark[MAXN],b,e;char s[6+2];void Insert(int u,int v){ node[u].child=&(mem[cnt++]=HASH(v,node[u].child));}void BFS(int u){    q[e++]=&node[u],node[u].f=0,node[u].depth=1;    while(b!=e){        NODE *t=q[b++];t->c=1;        for(HASH *p=t->child;p;p=p->next)            if(p->u!=t->f) q[e++]=&node[p->u],node[p->u].f=t->u,node[p->u].depth=t->depth+1;    }    for(int i=e-1;i>=0;i--)        if(q[i]->f){            node[q[i]->f].c+=q[i]->c;            if(q[i]->c>node[node[q[i]->f].son].c) node[q[i]->f].son=q[i]->u;        }    for(int i=1;i<=N;i++)        if(!node[i].mark){            node[i].mark=++cnt,mark[cnt]=i,node[i].belong=i;            for(int j=node[i].son;j;j=node[j].son)                if(!node[j].mark) node[j].mark=++cnt,mark[cnt]=j,node[j].belong=i;        }}void Pushup(ROOT &x){ x->s=x->lchild->s^x->rchild->s;}void Build(ROOT &x,int l,int r){    x=new TREE(l,r);    if(l==r){        x->s=node[mark[l]].v;        return;    }    int m=(l+r)>>1;    Build(x->lchild,l,m),Build(x->rchild,m+1,r);    Pushup(x);}int Find(ROOT &x,int l,int r){    if(x->l>=l && x->r<=r) return x->s;    int m=(x->l+x->r)>>1,ret=0;    if(l<=m) ret^=Find(x->lchild,l,r);    if(r>m) ret^=Find(x->rchild,l,r);    return ret;}int Query(int u,int v){    int ret=0;    while(node[u].belong!=node[v].belong){        if(node[node[u].belong].depth<node[node[v].belong].depth) swap(u,v);        ret^=Find(root,node[node[u].belong].mark,node[u].mark);        u=node[node[u].belong].f;    }    if(node[u].depth<node[v].depth) swap(u,v);    ret^=Find(root,node[v].mark,node[u].mark);    return ret;}void Change(ROOT &x,int p,int v){    if(x->l==x->r){        x->s=v;        return;    }    int m=(x->l+x->r)>>1;    if(p<=m) Change(x->lchild,p,v);    else Change(x->rchild,p,v);    Pushup(x);}int main(){    memset(node,0,sizeof(node));    scanf("%d",&N);    for(int i=1;i<=N;i++) scanf("%d",&node[i].v),node[i].u=i;    for(int i=1,u,v;i<N;i++){        scanf("%d %d",&u,&v);        Insert(u,v),Insert(v,u);    }    cnt=0,BFS(1);    Build(root,1,N);    scanf("%d",&Q);    for(int i=1,x,y;i<=Q;i++){        scanf("%s %d %d",&s,&x,&y);        if(s[0]==Q)            if(Query(x,y)) printf("Yes\n");            else printf("No\n");        if(s[0]==C) Change(root,node[x].mark,y);    }    return 0;}
View Code

(这代码现在貌似TLE了啊……懒得改了,貌似将动态内存改为静态就好)

BZOJ2819 Nim 树链剖分