是男人就过 8 题--Pony.AI 题A String Game(博弈 SG 后缀自动机)
将每个单轮的SG函数抑或可得最终结果。
为了计算SG函数,先对主串用后缀自动机处理,对输入的每个子串,先在自动机上走到对应串的节点,然后枚举后续状态,这些状态即为SG函数对应的后继状态,求SG函数,并将结果保存,否则会超时。
//http://www.cnblogs.com/IMGavin/ //https://nanti.jisuanke.com/t/24852 #include <iostream> #include <stdio.h> #include <cstdlib> #include <cstring> #include <queue> #include <vector> #include <map> #include <stack> #include <set> #include <bitset> #include <algorithm> using namespace std; typedef long long LL; #define gets(A) fgets(A, 1e8, stdin) const int INF = 0x3F3F3F3F, N = 200008, MOD = 1003; const int CH = 26; struct Node{ int ch[CH], fa, len, sg; void init(){ fa = -1; len = 0; sg = -1; memset(ch, 0xff, sizeof(ch)); } }sn[N]; struct SAM{ int cnt, last; SAM(){ cnt = last = 0; sn[cnt++].init(); } int newnode(){ sn[cnt].init(); return cnt++; } void add(int x){ //当前串T,加入字符x,p=ST(T),end=ST(Tx) int end = newnode(); sn[end].len = sn[last].len + 1; int v = last; //对p的所有没有标号x边的祖先v,trans(v,x) = end for(; v != -1 && sn[v].ch[x] == -1; v = sn[v].fa){ sn[v].ch[x] = end; } //查找p的第一个有x边的祖先v,若无,则fa[end]=root if(v == -1){ sn[end].fa = 0; }else{ //q=trans(v,x)若Max(q)==Max(v)+1,则fa[end]=q int q = sn[v].ch[x]; if(sn[v].len + 1 == sn[q].len){ sn[end].fa = q; }else{ //否则新建节点nq,trans(nq,*)=trans(q,x) //祖先关系由q->fa[q],改为q->nq->fa[q](更改前的fa[q]) int nq = newnode(); sn[nq] = sn[q]; sn[nq].len = sn[v].len + 1; sn[end].fa = sn[q].fa = nq; //对trans(v,x)==q的v,trans(v,x)改为nq for(; v != -1 && sn[v].ch[x] == q; v = sn[v].fa){ sn[v].ch[x] = nq; } } } last = end; } }; char str[N], p[N]; int dfs(int d){ if(sn[d].sg != -1){ return sn[d].sg; } bool st[27]; memset(st, 0, sizeof(st)); for(int i = 0; i < 26; i++){ if(sn[d].ch[i] != -1){ int sg = dfs(sn[d].ch[i]); if(sg <= 26){ st[sg] = true; } } } for(int i = 0; i <= 26; i++){ if(!st[i]){ sn[d].sg = i; return i; } } } int main(){ //freopen("out.txt", "w", stdout); while(~scanf("%s", str)){ SAM sa; for(int i = 0; str[i]; i++){ sa.add(str[i] - 'a'); } int t, ans = 0; scanf("%d", &t); while(t--){ scanf("%s", p); int st = 0; for(int i = 0; p[i]; i++){ st = sn[st].ch[p[i] - 'a']; } ans ^= dfs(st); } if(ans){ printf("Alice\n"); }else{ printf("Bob\n"); } } return 0; }