BZOJ2819 Nim 树链剖分
Posted WDZRMPCBIT
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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; }
(这代码现在貌似TLE了啊……懒得改了,貌似将动态内存改为静态就好)
以上是关于BZOJ2819 Nim 树链剖分的主要内容,如果未能解决你的问题,请参考以下文章