AT3727 [ARC087C] Prefix-free Game 题解
Description.
如果两个字符串互不为前缀,那就定义它们是好的对。
一个字符串集是好的,当且仅当:
- 字符串集中的所有元素两两都是好的
- 字符集中所有元素都是由
0
和1
构成的 - 字符集中所有元素长度都 ≤L(L≤1018)≤L(L≤1018)
Alice 和 Bob 打隔膜,每次他们可以加入一个字符串,需要满足插入后集合还是好的。
谁不能插入了谁是人输,问谁是人赢。
保证初始字符串集的长度和 ≤105≤105
Solution.
首先建出 01Trie
。
然后相当于这个 Trie
上的所有节点都不能选择了。
这个 Trie
距离 满Trie
差的点都是可以选择的。
选择一个点后它所有祖先都和所有后代都不能选择。
手模样例后发现,我们需要考虑的就是很多棵小 满Trie
,它们之间互不干扰。
看到互不干扰,就想到可以用 SG函数
来解决这个问题。
我们只需要考虑一棵深度为 L(L≤1018)L(L≤1018) 的 满Trie
的 SG函数
,再全部 ⊕⊕ 起来即可。
设一棵深度为 xx 的 满trie
的 SG函数
是 SGxSGx
SGx={0x=0mexxi=1(⨁x−1j=iSGj)x>0SGx={0x=0mexxi=1(⨁x−1j=iSGj)x>0
因为 x≤L≤1018x≤L≤1018,所以递推肯定不可能,必须要 O(1)O(1) 或 O(logN)O(logN) 算。
打表发现,SGi=lowbit(i)SGi=lowbit(i),然后就可以 O(1)O(1) 计算 SGxSGx 了。
同时,插入一个长度为 nn 的字符串最多会产生 n+1n+1 个满二叉树,所以满二叉树总数量是 O(n)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;
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Java 中堆内存和栈内存上的数据分布和特点
· 开发中对象命名的一点思考
· .NET Core内存结构体系(Windows环境)底层原理浅谈
· C# 深度学习:对抗生成网络(GAN)训练头像生成模型
· .NET 适配 HarmonyOS 进展
· 本地部署 DeepSeek:小白也能轻松搞定!
· 如何给本地部署的DeepSeek投喂数据,让他更懂你
· 从 Windows Forms 到微服务的经验教训
· 李飞飞的50美金比肩DeepSeek把CEO忽悠瘸了,倒霉的却是程序员
· 超详细,DeepSeek 接入PyCharm实现AI编程!(支持本地部署DeepSeek及官方Dee