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


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

    总的节点数可能超过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;
    }
  • 相关阅读:
    Jenkins可用环境变量列表以及环境变量的使用(Shell/Command/Maven/Ant)
    CreateJS结合Falsh工具生成Canvas动画(加密字符串的由来)
    Linux下使用mv重命名文件或者移动文件(增强版的工具为rename)
    Windows7/8/10中无法识别USB设备的问题解决
    Eclipse工程中Java Build Path中的JDK版本和Java Compiler Compiler compliance level的区别(转)
    使用Docker部署Spring boot项目
    豆瓣API
    scrapy
    elasticsearch x-pack
    Document
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/4340971.html
Copyright © 2020-2023  润新知