• UOJ#266. 【清华集训2016】Alice和Bob又在玩游戏 博弈,DSU on Tree,Trie


    原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ266.html

    题解

    首先我们可以直接暴力 $O(n^2)$ 用 sg 函数来算答案。

    对于一个树就是枚举一下从根出发到哪一个节点为止的路径被删掉了,剩下所有的子树的sg值xor起来,对于每一个路径后的答案取一个 mex 。

    我们考虑快速的做这个过程。

    直接写个 Trie 再 DSU on tree 就好了,只要支持查询 mex 和整棵 trie 对某一个值 xor 这两种操作就好了。

    时间复杂度 $O(nlog ^2n)$ 。

    P.S. 可以用线段树合并优化复杂度。

    代码

    #pragma GCC optimize("Ofast","inline")
    #include <bits/stdc++.h>
    #define clr(x) memset(x,0,sizeof (x))
    #define For(i,a,b) for (int i=a;i<=b;i++)
    #define Fod(i,b,a) for (int i=b;i>=a;i--)
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    #define _SEED_ ('C'+'L'+'Y'+'A'+'K'+'I'+'O'+'I')
    #define outval(x) printf(#x" = %d
    ",x)
    #define outvec(x) printf("vec "#x" = ");for (auto _v : x)printf("%d ",_v);puts("")
    #define outtag(x) puts("----------"#x"----------")
    #define outarr(a,L,R) printf(#a"[%d...%d] = ",L,R);
    						For(_v2,L,R)printf("%d ",a[_v2]);puts("");
    using namespace std;
    typedef long long LL;
    LL read(){
    	LL x=0,f=0;
    	char ch=getchar();
    	while (!isdigit(ch))
    		f|=ch=='-',ch=getchar();
    	while (isdigit(ch))
    		x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
    	return f?-x:x;
    }
    const int N=100005;
    namespace Trie{
    	const int S=N*20*20;
    	int son[S][2],size[S],c=0;
    	#define ls son[x][0]
    	#define rs son[x][1]
    	void Init(){
    		while (c)
    			clr(son[c]),size[c]=0,c--;
    	}
    	void Ins(int &x,int d,int v,int tag){
    		if (!x)
    			x=++c,size[x]=1;
    		if (d<0)
    			return;
    		Ins(son[x][(v^tag)>>d&1],d-1,v,tag);
    		size[x]=size[ls]+size[rs];
    	}
    	void Get(int x,int d,int v,int tag,vector <int> &vec){
    		if (!x)
    			return;
    		if (d<0)
    			return vec.pb(v);
    		Get(son[x][tag>>d&1],d-1,v,tag,vec);
    		Get(son[x][~tag>>d&1],d-1,v|(1<<d),tag,vec);
    	}
    	int Ask(int x,int d,int v,int tag){
    		if (d<0)
    			return v;
    		if (size[son[x][tag>>d&1]]<(1<<d))
    			return Ask(son[x][tag>>d&1],d-1,v,tag);
    		else
    			return Ask(son[x][~tag>>d&1],d-1,v|(1<<d),tag);
    	}
    	#undef ls
    	#undef rs
    }
    int n,m;
    vector <int> e[N];
    struct trie{
    	int rt,tag;
    }t[N];
    int cnt;
    int size[N],son[N],sg[N],id[N];
    void dfs(int x,int pre){
    	size[x]=1,son[x]=0;
    	for (auto y : e[x])
    		if (y!=pre){
    			dfs(y,x);
    			size[x]+=size[y];
    			if (!son[x]||size[son[x]]<size[y])
    				son[x]=y;
    		}
    }
    vector <int> gid;
    void dfs2(int x,int pre){
    	sg[x]=0;
    	int s=0;
    	for (auto y : e[x])
    		if (y!=pre){
    			dfs2(y,x);
    			s^=sg[y];
    		}
    	if (!son[x])
    		id[x]=++cnt,t[cnt].rt=t[cnt].tag=0;
    	else
    		t[id[x]=id[son[x]]].tag^=s^sg[son[x]];
    	trie &now=t[id[x]];
    	Trie::Ins(now.rt,17,s,now.tag);
    	for (auto y : e[x])
    		if (y!=pre&&y!=son[x]){
    			gid.clear();
    			Trie::Get(t[id[y]].rt,17,0,t[id[y]].tag,gid);
    			for (auto v : gid)
    				Trie::Ins(now.rt,17,v^(s^sg[y]),now.tag);
    		}
    	sg[x]=Trie::Ask(now.rt,17,0,now.tag);
    }
    void Main(){
    	n=read(),m=read();
    	For(i,0,n)
    		e[i].clear(),size[i]=0;
    	For(i,1,m){
    		int x=read(),y=read();
    		e[x].pb(y),e[y].pb(x);
    	}
    	cnt=0;
    	int ans=0;
    	Trie::Init();
    	For(i,1,n)
    		if (!size[i]){
    			dfs(i,0);
    			dfs2(i,0);
    			ans^=sg[i];
    		}
    	puts(ans?"Alice":"Bob");
    }
    int main(){
    	int T=read();
    	while (T--)
    		Main();
    	return 0;
    }
    

      

  • 相关阅读:
    牛客练习赛64 D-宝石装箱(容斥定律,背包)
    CF-GYM-[2019 USP Try-outs] 部分题解
    [Codeforces Round #642 (Div. 3)] ABCDEF题解
    [NCD 2019] G. Ali and the Breakfast (解析几何)
    [AtCoder Beginner Contest 165] E
    [Educational Codeforces Round 86 (Rated for Div. 2)] E. Placing Rooks (组合数学,容斥定律)
    [AtCoder Beginner Contest 164] -E
    牛客算法周周练3 C -小雨坐地铁(分层最短路)
    HDU 5726 GCD (RMQ + 二分)
    Codeforces Round #362 (Div. 2) C. Lorenzo Von Matterhorn (类似LCA)
  • 原文地址:https://www.cnblogs.com/zhouzhendong/p/UOJ266.html
Copyright © 2020-2023  润新知