题意

给一个字符串\(s\),和\(n\)个子串\(t[i]\),两个人博弈,每次取出一个串\(t[i]\),在后面加入一个字符,保证新字符串仍然是\(s\)的子串,无法操作的人输。

分析

  • n个子串,类比于n堆石子,如果把子串\(t[i]\)在后面加若干字符能生成的子串看出一个状态,用一个数表示,那每次状态的变化,就类比于对一堆石子取走若干个,无法操作,就类比于没有石子可以取。
  • 多堆取石子游戏的做法就是把每堆石子的SG值(sg(x)=x)异或起来,不为零就先手赢,否则后手赢。
  • 所以可以将题目转化为求每个子串\(t[i]\)对应状态的SG值。
  • 然后就是后缀自动机的套路,每个子串就可以对应SAM上的一个节点,所以可以直接dfs记忆化搜索SG值。

代码

#include <bits/stdc++.h>
using namespace std;
const int N=1e5+50;
char s[N];
int n;
struct SAM{
int nex[N*2][26],fa[N*2],len[N*2],num[N*2];
int cnt,lst;
int sg[N*2];
int newnode(int l,int s){
for(int i=0;i<26;i++){
nex[cnt][i]=0;
}
len[cnt]=l;
num[cnt]=s;
return cnt++;
}
void init(){
cnt=0;
lst=newnode(0,0);
fa[lst]=-1;
memset(sg,-1,sizeof(sg));
}
void add(int c){
c-='a';
int p=lst;
int cur=newnode(len[p]+1,1);
while(p!=-1 && !nex[p][c]){
nex[p][c]=cur;
p=fa[p];
}
if(p==-1){
fa[cur]=0;
}else{
int q=nex[p][c];
if(len[q]==len[p]+1){
fa[cur]=q;
}else{
int cl=newnode(len[p]+1,0);
fa[cl]=fa[q];
memcpy(nex[cl],nex[q],sizeof(nex[cl]));
while(p!=-1 && nex[p][c]==q){
nex[p][c]=cl;
p=fa[p];
}
fa[q]=fa[cur]=cl;
}
}
lst=cur;
}
int w[N*2],tp[N*2];
void dfs(int u){
int vis[30]={0};
if(sg[u]!=-1){
return;
}
for(int i=0;i<26;i++){
int v=nex[u][i];
if(v){
dfs(v);
vis[sg[v]]=1;
}
}
for(int i=0;i<26;i++){
if(!vis[i]){
sg[u]=i;
break;
}
}
}
void sfd(int l){
for(int i=0;i<=l;i++){
w[i]=0;
}
for(int i=1;i<=cnt;i++){
w[len[i]]++;
}
for(int i=2;i<=l;i++){
w[i]+=w[i-1];
}
for(int i=cnt-1;i>=1;i--){
tp[w[len[i]]--]=i;
}
sg[lst]=0;
int vis[30]={0};
for(int i=cnt-1;i>=0;i--){
int u=tp[i];
memset(vis,0,sizeof(vis));
for(int j=0;j<26;j++){
int v=nex[u][j];
if(v){
vis[sg[v]]=1;
}
}
for(int j=0;j<26;j++){
if(!vis[j]){
sg[u]=j;
break;
}
}
}
}
int solve(char *s){
int rt=0;
int l=strlen(s);
for(int j=0;j<l;j++){
rt=nex[rt][s[j]-'a'];
}
return sg[rt];
}
}ac;
int main(){
// freopen("in.txt","r",stdin);
while(~scanf("%s",s)){
ac.init();
int len=strlen(s);
for(int i=0;i<len;i++){
ac.add(s[i]);
}
//dfs或者拓扑排序求sg函数
// ac.dfs(0);
ac.sfd(len);
scanf("%d",&n);
int ans=0;
for(int i=1;i<=n;i++){
scanf("%s",s);
ans^=ac.solve(s);
}
if(ans){
printf("Alice\n");
}else{
printf("Bob\n");
}
}
return 0;
}

是男人就过八题A_A String Game题解的更多相关文章

  1. poj 1741 楼教主男人八题之中的一个:树分治

    http://poj.org/problem? id=1741 Description Give a tree with n vertices,each edge has a length(posit ...

  2. poj 1737男人八题之一 orz ltc

    这是楼教主的男人八题之一.很高兴我能做八分之一的男人了. 题目大意:求有n个顶点的连通图有多少个. 解法: 1.  用总数减去不联通的图(网上说可以,我觉得时间悬) 2.    用动态规划(数学递推) ...

  3. POJ1742 Coins(男人八题之一)

    前言 大名鼎鼎的男人八题,终于见识了... 题面 http://poj.org/problem?id=1742 分析 § 1 多重背包 这很显然是一个完全背包问题,考虑转移方程: DP[i][j]表示 ...

  4. Cogs 1714. [POJ1741][男人八题]树上的点对(点分治)

    [POJ1741][男人八题]树上的点对 ★★★ 输入文件:poj1741_tree.in 输出文件:poj1741_tree.out 简单对比 时间限制:1 s 内存限制:256 MB [题目描述] ...

  5. 《学习OpenCV》练习题第四章第八题ab

    这道题是利用OpenCV例子程序里自带的人脸检测程序,做点图像的复制操作以及alpha融合. 说明:人脸检测的程序我参照了网上现有的例子程序,没有用我用的OpenCV版本(2.4.5)的facedet ...

  6. 经典算法题每日演练——第八题 AC自动机

    原文:经典算法题每日演练--第八题 AC自动机 上一篇我们说了单模式匹配算法KMP,现在我们有需求了,我要检查一篇文章中是否有某些敏感词,这其实就是多模式匹配的问题. 当然你也可以用KMP算法求出,那 ...

  7. 【20171026早】alert(1) to win - 第六、七、八题

    早上7点起床,又写了一篇小说发在了起点网上,有兴趣的可以看看.点击这里 忙完后,继续练习,刚开始发现自己答题的速度有些慢,可能是因为对于html,javascript知识不是很精通,但是话又说回来,谁 ...

  8. [是男人就过8题——Pony.ai]Perfect N-P Arrays

    [是男人就过8题--Pony.ai]Perfect N-P Arrays 题目大意: 一棵\(n(\sum n\le5\times10^6)\)个结点的树,每个结点都有一个括号.求树上一个合法的括号序 ...

  9. noip做题记录+挑战一句话题解?

    因为灵巧实在太弱辽不得不做点noip续下命QQAQQQ 2018 积木大赛/铺设道路 傻逼原题? 然后傻逼的我居然检查了半天是不是有陷阱最后花了差不多一个小时才做掉我做过的原题...真的傻逼了我:( ...

随机推荐

  1. lightoj 1145 - Dice (I)(dp+空间优化+前缀和)

    题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1145 题解:首先只要是dp的值只和上一个状态有关系那么就可以优化一维,然后这题 ...

  2. atcoder D - 11(组合数学)

    题目链接:http://arc077.contest.atcoder.jp/tasks/arc077_b 题解:有n+1个数只有一个数字是有重复出现的,要求一共有多少不同的组合显然和这两个数的位置有关 ...

  3. PAT L3-015. 球队“食物链”

    L3-015. 球队“食物链” 时间限制 1000 ms 内存限制 262144 kB 代码长度限制 8000 B 判题程序 Standard 作者 李文新(北京大学) 某国的足球联赛中有N支参赛球队 ...

  4. PAT L1-043. 阅览室

    L1-043. 阅览室 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 天梯图书阅览室请你编写一个简单的图书借阅统计程序.当读者 ...

  5. List集合的排序

    最近在写需求时,将某张表中的短信信息拿出,sql写完后,取出来后的结构是List<Map>,在进行到某一步时需要将这个List<Map>进行逆序排序, 当时第一想法便是写一个f ...

  6. Node基础-CommonJS模块化规范

    1.在本地项目中基于NPM/YARN安装第三方模块 第一步:在本地项目中创建一个"package.json"的文件 作用:把当前项目所有依赖的第三方模块信息(包含:模块名称以及版本 ...

  7. springboot应用监控和管理

    spring boot应用监控和管理 Spring Boot 监控核心是 spring-boot-starter-actuator 依赖,增加依赖后, Spring Boot 会默认配置一些通用的监控 ...

  8. spring boot项目后台运行

    spring boot项目后台运行 Spring Boot应用的几种运行方式: (1)运行Spring Boot的应用主类 (2)使用Maven的Spring Boot插件mvn spring-boo ...

  9. 二分练习题2 查找大于等于x的最小元素 题解

    题目描述 现在告诉你一个长度为 \(n\) 的有序数组 \(a_1, a_2, ..., a_n\) ,以及 \(q\) 次询问,每次询问会给你一个数 \(x\) ,对于每次询问,你需要输出数组 \( ...

  10. C++输入输出常用格式(cin,cout,stringstream)

    输入格式 1.cin>>a; 最基本的格式,适用于各种类型.会过滤掉不可见字符例如空格,TAB,回车等 2.cin>>noskipws>>ch[i]; 使用了 no ...