Description.
如果两个字符串互不为前缀,那就定义它们是好的对。
一个字符串集是好的,当且仅当:
- 字符串集中的所有元素两两都是好的
- 字符集中所有元素都是由
0
和1
构成的 - 字符集中所有元素长度都 \(\le L(L\le 10^{18})\)
Alice 和 Bob 打隔膜,每次他们可以加入一个字符串,需要满足插入后集合还是好的。
谁不能插入了谁是人输,问谁是人赢。
保证初始字符串集的长度和 \(\le 10^5\)
Solution.
首先建出 01Trie
。
然后相当于这个 Trie
上的所有节点都不能选择了。
这个 Trie
距离 满Trie
差的点都是可以选择的。
选择一个点后它所有祖先都和所有后代都不能选择。
手模样例后发现,我们需要考虑的就是很多棵小 满Trie
,它们之间互不干扰。
看到互不干扰,就想到可以用 SG函数
来解决这个问题。
我们只需要考虑一棵深度为 \(L(L\le 10^{18})\) 的 满Trie
的 SG函数
,再全部 \(\oplus\) 起来即可。
设一棵深度为 \(x\) 的 满trie
的 SG函数
是 \(SG_x\)
\[SG_x=\begin{cases}
0&x=0\\
\text{mex}_{i=1}^x\left({\bigoplus_{j=i}^{x-1}SG_j}\right)&x>0
\end{cases}
\]
因为 \(x\le L\le 10^{18}\),所以递推肯定不可能,必须要 \(O(1)\) 或 \(O(\log N)\) 算。
打表发现,\(SG_i=\text{lowbit}(i)\),然后就可以 \(O(1)\) 计算 \(SG_x\) 了。
同时,插入一个长度为 \(n\) 的字符串最多会产生 \(n+1\) 个满二叉树,所以满二叉树总数量是 \(O(n)\) 级别的。
然后这题就做完了。
Coding.
点击查看一个巨弱的代码
//是啊,你就是那只鬼了,所以被你碰到以后,就轮到我变成鬼了{{{
#include<bits/stdc++.h>
using namespace std;typedef long long ll;
template<typename T>inline void read(T &x)
{
x=0;char c=getchar(),f=0;
for(;c<48||c>57;c=getchar()) if(!(c^45)) f=1;
for(;c>=48&&c<=57;c=getchar()) x=(x<<1)+(x<<3)+(c^48);
f?x=-x:x;
}/*}}}*/
int n,ch[2000005][2],d[2000005],tt,rt;char s[100005];ll L;
inline void ins(int &x,char *s,int dep,int lim)
{
d[x?x:x=++tt]=dep-1;if(dep==lim+1) return;
ins(ch[x][s[dep]-'0'],s,dep+1,lim);
}
inline ll sg(ll x) {return x&(-x);}
inline ll dfs(int x) {return (ch[x][0]?dfs(ch[x][0]):sg(L-d[x]))^(ch[x][1]?dfs(ch[x][1]):sg(L-d[x]));}
int main()
{
read(n),read(L);for(int i=1;i<=n;i++) scanf("%s",s+1),ins(rt,s,1,strlen(s+1));
return puts(dfs(rt)?"Alice":"Bob"),0;
}