[BZOJ1398] 寻找主人 Necklace

Description

给定两个串 (S,T),判断它们是否循环同构,如果是则输出它的最小循环表示。

Solution

考虑把两个串的最小循环表示都算出来,然后判断它们是否相等

把串翻倍建 SAM,然后贪心地走最小转移边 (len) 次即可

(强行缩了一些内存结果居然混过去了

#include <bits/stdc++.h>
using namespace std;
const int Maxn = 4000005;

#define reset(x) memset(x,0,sizeof x)

struct Suffix_Automata
{
    int maxlen[Maxn], trans[Maxn][10], link[Maxn], Size, Last;

    void clear()
    {
        reset(maxlen);
        reset(trans);
        reset(link);
        Size = Last = 1;
    }

    Suffix_Automata()
    {
        clear();
    }

    inline void extend(int id)
    {
        int cur = (++ Size), p;
        maxlen[cur] = maxlen[Last] + 1;
        for (p = Last; p && !trans[p][id]; p = link[p]) trans[p][id] = cur;
        if (!p) link[cur] = 1;
        else
        {
            int q = trans[p][id];
            if (maxlen[q] == maxlen[p] + 1) link[cur] = q;
            else
            {
                int clone = (++ Size);
                maxlen[clone] = maxlen[p] + 1;
                for(int i=0; i<10; i++) trans[clone][i] = trans[q][i];
                link[clone] = link[q];
                for (; p && trans[p][id] == q; p = link[p]) trans[p][id] = clone;
                link[cur] = link[q] = clone;
            }
        }
        Last = cur;
    }
    string solve(int n)
    {
        int p=1;
        string res;
        for(int i=0; i<n; i++)
        {
            for(int j=0; j<10; j++)
            {
                if(trans[p][j])
                {
                    res+='0'+j;
                    p=trans[p][j];
                    break;
                }
            }
        }
        return res;
    }
} sam;

int main()
{
    ios::sync_with_stdio(false);
    string str;
    int n;
    string r[2];
    for(int i=0; i<2; i++)
    {
        sam.clear();
        cin>>str;
        n=str.length();
        for(int j=0; j<n; j++) sam.extend(str[j]-'0');
        for(int j=0; j<n; j++) sam.extend(str[j]-'0');
        r[i]=sam.solve(n);
    }
    if(r[0]==r[1])
    {
        cout<<"Yes"<<endl;
        cout<<r[0]<<endl;
    }
    else
    {
        cout<<"No"<<endl;
    }
}


原文地址:https://www.cnblogs.com/mollnn/p/13282872.html