• [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;
        }
    }
    
    
    
  • 相关阅读:
    Golang之ring.Ring的Link操作
    Servlet3.0新特性之web-fragment.xml模块化配置文件
    使用filter代替jsp获取参数
    数据库中常用的字符串截取函数-总结
    js判断两字符串是否相等不区分大小写
    java读取excle内容(类似表结构)
    postgreSQL数据库分页查询
    3D轮播图案例
    3D立方体案例
    去除HTML双击背景和input框取消输入颜色
  • 原文地址:https://www.cnblogs.com/mollnn/p/13282872.html
Copyright © 2020-2023  润新知