Calculator A String Game SG function + suffix automaton

meaning of the title

give a string t and n indivual t substring of s [ 1.. n ] . Two people take turns to operate, each time you can choose a string s [ i ] , then in s [ i ] Add a string at the end of , so that the new string obtained is still a substring of t. The operator cannot lose, ask whether the first mover will win or the second mover will win.
t 10 5 , | s [ i ] | 3 10 7

analyze

Building teaching is the easiest question among the 8 questions that a man has passed, so how can I say that I am already 1 8 a man.
First build a suffix automaton, adding a character after a string is equivalent to shifting its corresponding node on sam one bit backward on the DAG.
Then we can preprocess the SG value of each point on the suffix automaton, and then the XOR sum of the SG value of each string is the answer.

code

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<queue>

const int N=200005;

int sz,last,mx[N],ch[N][26],a[N],deg[N],fa[N],sg[N],t[N];
char str[30000005];
std::queue<int> que;

void extend(int x)
{
    int p,q,np,nq;
    p=last;last=np=++sz;mx[np]=mx[p]+1;
    for (;p&&!ch[p][x];p=fa[p]) ch[p][x]=np;
    if (!p) fa[np]=1;
    else
    {
        q=ch[p][x];
        if (mx[q]==mx[p]+1) fa[np]=q;
        else
        {
            nq=++sz;mx[nq]=mx[p]+1;
            memcpy(ch[nq],ch[q],sizeof(ch[q]));
            fa[nq]=fa[q];fa[q]=fa[np]=nq;
            for (;ch[p][x]==q;p=fa[p]) ch[p][x]=nq;
        }
    }
}

void pre()
{
    for (int i=1;i<=sz;i++) deg[i]=sg[i]=0;
    for (int i=1;i<=sz;i++)
        for (int j=0;j<26;j++)
            if (ch[i][j]) deg[ch[i][j]]++;
    for (int i=1;i<=sz;i++) if (!deg[i]) que.push(i);
    int tot=0;
    while (!que.empty())
    {
        int x=que.front();que.pop();
        a[++tot]=x;
        for (int i=0;i<26;i++)
            if (ch[x][i])
            {
                deg[ch[x][i]]--;
                if (!deg[ch[x][i]]) que.push(ch[x][i]);
            }
    }
    for (int i=sz;i>=1;i--)
    {
        int x=a[i];
        for (int j=0;j<26;j++)
            if (ch[x][j]) t[sg[ch[x][j]]]=1;
        for (int j=0;;j++) if (!t[j]) {sg[x]=j;break;}
        for (int j=0;j<26;j++)
            if (ch[x][j]) t[sg[ch[x][j]]]=0;
    }
}

int main()
{
    while (scanf("%s",str)!=EOF)
    {
        for (int i=1;i<=sz;i++)
            for (int j=0;j<26;j++)
                ch[i][j]=0;
        for (int i=1;i<=sz;i++) fa[i]=mx[i]=0;
        sz=last=1;
        int len=strlen(str);
        for (int i=0;i<len;i++) extend(str[i]-'a');
        pre();
        int n,ans=0;
        scanf("%d",&n);
        while (n--)
        {
            scanf("%s",str);len=strlen(str);
            int x=1;
            for (int i=0;i<len;i++) x=ch[x][str[i]-'a'];
            ans^=sg[x];
        }
        puts(ans?"Alice":"Bob");
    }
    return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324827642&siteId=291194637