码迷,mamicode.com
首页 > 其他好文 > 详细

【块状树】【博弈论】bzoj3729 Gty的游戏

时间:2015-03-16 08:39:44      阅读:649      评论:0      收藏:0      [点我收藏+]

标签:

块状树,每个块的根记录一下当前块内距块根为奇数距离的异或和和偶数距离的异或和,询问的时候讨论一下即可。

总的节点数可能超过50000。

#include<cstdio>
#include<cmath>
using namespace std;
#define N 100001
int n,m,L,a[N];
int en,v[N<<1],next[N<<1],first[N];
int e2,v2[N<<1],nex2[N<<1],firs2[N];
int sz,top[N],siz[N],fa[N],xorv[2][N],meiz,dep[N];
void AddEdge(int U,int V)
{
	v[++en]=V;
	next[en]=first[U];
	first[U]=en;
}
void AddEdg2(int U,int V)
{
	v2[++e2]=V;
	nex2[e2]=firs2[U];
	firs2[U]=e2;
}
void makeblock(int U)
{
	for(int i=first[U];i;i=next[i])
	  if(v[i]!=fa[U])
	    {
	      fa[v[i]]=U;
	      dep[v[i]]=dep[U]+1;
	      if(siz[top[U]]<sz)
	        {
	          ++siz[top[U]];
	          top[v[i]]=top[U];
	        }
	      makeblock(v[i]);
	    }
}
void makeGoto(int U)
{
    for(int i=first[U];i;i=next[i])
      if(v[i]!=fa[U])
        {
          if(top[v[i]]!=top[U])
            AddEdg2(top[U],v[i]);
          makeGoto(v[i]);
        }
}
void dfs_init(int U,bool d)
{
	xorv[d][top[U]]^=a[U];
	for(int i=first[U];i;i=next[i])
	  if(v[i]!=fa[U]&&top[v[i]]==top[U])
	    dfs_init(v[i],d^1);
}
int ans;
void dfs_Goto(int U,bool d)
{
	ans^=xorv[d][top[U]];
	for(int i=firs2[U];i;i=nex2[i])
	  dfs_Goto(v2[i],d^((dep[v2[i]]-dep[U])&1));
}
void dfs_block(int U,bool d)
{
	if(d) ans^=a[U];
	for(int i=first[U];i;i=next[i])
	  if(v[i]!=fa[U])
	    {
	      if(top[v[i]]==top[U])
	        dfs_block(v[i],d^1);
	      else
	        dfs_Goto(v[i],d);
	    }
}
void query(int U)
{
	ans=0;
	if(U==top[U]) dfs_Goto(U,1);
	else dfs_block(U,0);
}
void Update(int U,int x)
{
	xorv[0][top[U]]=xorv[1][top[U]]=0;
	a[U]=x%(L+1);
	dfs_init(top[U],0);
}
void AddNode(int U,int V,int x)
{
	++n;
	fa[V]=U;
	dep[V]=dep[U]+1;
	if(siz[top[U]]<sz)
      {
        top[V]=top[U];
        ++siz[top[V]];
      }
    else
      {
        top[V]=V;
        siz[V]++;
        AddEdg2(top[U],V);
      }
    AddEdge(U,V);
    a[V]=x%(L+1);
    xorv[(dep[V]-dep[top[V]])&1][top[V]]^=a[V];
}
int main()
{
	int x,y,c,op;
	scanf("%d%d",&n,&L);
	for(int i=1;i<=n;++i)
	  {
	  	scanf("%d",&a[i]);
	  	top[i]=i;
	  	siz[i]=1;
	  	a[i]%=(L+1);
	  }
	for(int i=1;i<n;++i)
	  {
	  	scanf("%d%d",&x,&y);
	  	AddEdge(x,y);
	  	AddEdge(y,x);
	  }
	sz=sqrt(n);
	makeblock(1);
	makeGoto(1);
	for(int i=1;i<=n;++i)
	  if(top[i]==i)
	    dfs_init(i,0);
	scanf("%d",&m);
	for(;m;--m)
	  {
	  	scanf("%d%d",&op,&x); x^=meiz;
	  	if(op==1)
	  	  {
	  	  	query(x);
	  	  	if(ans)
	  	  	  {
	  	  	  	++meiz;
	  	  	  	puts("MeiZ");
	  	  	  }
	  	  	else puts("GTY");
	  	  }
	  	else if(op==2)
	  	  {
	  	  	scanf("%d",&c); c^=meiz;
	  	  	Update(x,c);
	  	  }
	  	else
	  	  {
	  	  	scanf("%d%d",&y,&c); y^=meiz; c^=meiz;
	  	  	AddNode(x,y,c);
	  	  }
	  }
	return 0;
}

【块状树】【博弈论】bzoj3729 Gty的游戏

标签:

原文地址:http://www.cnblogs.com/autsky-jadek/p/4340971.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!