The following:
Gives a substring of a string t and N T S[1..N] s [1.. n] S[1..N]. Two people rotate, each time you can select a string s[i] s [i] s[i], then add a string at the end of S[i] s [i] s[i], and the new string that satisfies is still a substring of T. Can not be the author loses, asked whether the winning or the win.
t≤105,∑|s[i]|≤3∗107 t≤10 5, ∑| s [i] | ≤3∗107 t≤10^5,∑|s[i]|≤3∗107 :
Provincial election before a wave template ...
SAM+SG the naked question.
Code
#include <cstdio> #include <cstdlib> #include <iostream> #include <cstring> struct sam{int a[26]
, Max,par;
}sam[200010];int tot=1,root,tail,sg[200010];
int check[20][200010],tim=0;
void Addsam (int c,int len) {int p=tail,np=++tot;
Sam[np].max=len;
For (;p &&!sam[p].a[c];p =sam[p].par) SAM[P].A[C]=NP;
TAIL=NP;
if (!p) sam[np].par=root;
else {int q=sam[p].a[c];
if (sam[q].max==sam[p].max+1) sam[np].par=q;
else {int nq=++tot;sam[nq]=sam[q];
sam[nq].max=sam[p].max+1;
SAM[Q].PAR=SAM[NP].PAR=NQ;
for (;p &&sam[p].a[c]==q;p=sam[p].par) sam[p].a[c]=nq;
}} char s[100010];
void solve (int x) {if (sg[x]!=-1) return;
int Tmp=++tim;
for (int i=0;i<26;i++) if (Sam[x].a[i]) solve (Sam[x].a[i]), check[sg[sam[x].a[i]]][x]=tmp;
for (int i=0;i<=27;i++) if (check[i][x]!=tmp) {Sg[x]=i;break}} int main () {while (scanf ("%s"), S+1) {int Len=strlen (s+1)!=eof);
for (int i=1;i<=tot;i++) for (int j=0;j<26;j++) sam[i].a[j]=0;
tot=root=tail=1;
for (int i=1;i<=len;i++) Addsam (s[i]-' a ', i);
for (int i=1;i<=tot;i++) sg[i]=-1;
Solve (root);
int n;scanf ("%d", &n);
int ans=0;
while (n--) {scanf ("%s", s+1);
Len=strlen (s+1); int x=root;
for (int i=1;i<=len;i++) x=sam[x].a[s[i]-' a '];
ANS^=SG[X];
if (ans) puts ("Alice");
Else puts ("Bob"); }
}