[ARC087]E - Prefix-free Game Trie树+SG函数

题面
考虑把所有输入的字符串看成一棵二叉Trie树(深度为 L ),那么一个字符串所在的点到根节点的路径及其子树中不能有其他的点。
现在双方的操作就是在Trie树上轮流放点,也就是取走一个以x为根的子树(要满足 x 到根及其子树中没有点),谁不能取谁输。可以发现,在一棵完整的深度为T的树中取走一个深度为 S 的子树,会生成出深度为S,S+1,...,T1的子树各一个。
所以取深度为 X 的树的SG函数:

SG(X)=mex{0,SG(X1),SG(X1)xorSG(X2),...,SG(X1)xor...xorSG(1)}

打表发现:
SG(X)=lowbit(X)

写一棵Trie树把一开始能取的树找出来,把它们的 SG 函数值异或起来就可以判断了。
代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#define ll long long
using namespace std;
const int maxn=200010;
int n,tr[maxn][2],bg[maxn],tot=1;ll L;
bool num[100];
char s[maxn];
int lowbit(ll x)
{
    int r=0;
    for(;!(x&1);r++,x>>=1);
    return r;
}
void ins(int v,int id,int d,int len)
{
    if(tr[v][s[bg[id]+d-1]-'0']==0)     tr[v][s[bg[id]+d-1]-'0']=++tot;
    if(d!=len) ins(tr[v][s[bg[id]+d-1]-'0'],id,d+1,len);
}
void dfs(int v,int d)
{
    for(int k=0;k<=1;k++)
        if(tr[v][k]==0) {if(L-d>0) num[lowbit(L-d)]^=1;}
        else dfs(tr[v][k],d+1);
}
int main()
{
    scanf("%d%lld",&n,&L);
    int top=0;
    for(int i=1;i<=n;i++)
    {
        bg[i]=top+1;
        scanf("%s",s+bg[i]);
        top+=strlen(s+bg[i]);
        ins(1,i,1,strlen(s+bg[i]));
    }
    dfs(1,0);
    for(int i=0;i<=60;i++) if(num[i]) {puts("Alice");return 0;}
    puts("Bob");
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值