[BZOJ1398] 寻找主人 Necklace - 后缀自动机,最小表示法

Description

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

Solution

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

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

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

#include 
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>str;
        n=str.length();
        for(int j=0; j

你可能感兴趣的:([BZOJ1398] 寻找主人 Necklace - 后缀自动机,最小表示法)