zoukankan      html  css  js  c++  java
  • BZOJ2882 工艺【SAM】 最小循环串

    BZOJ2882 工艺

    给出一个串,要求其循环同构串中字典序最小的那个
    串翻倍建(SAM)然后从起点开始贪心的跑(n)次即可

    当然也能用最小表示法来做

    #include<bits/stdc++.h>
    using namespace std;
    const int MAXN = 6e5+7;
    int n,A[MAXN];
    struct SAM{
        int len[MAXN<<1],link[MAXN<<1],tot,last;
        map<int,int> ch[MAXN<<1];
        SAM(){ link[len[0] = tot = last = 0] = -1; }
        void extend(int x){
            int np = ++tot, p = last; len[np] = len[last] + 1;
            while(p!=-1 and !ch[p].count(x)){
                ch[p].insert(make_pair(x,np));
                p = link[p];
            }
            if(p==-1) link[np] = 0;
            else{
                int q = ch[p].at(x);
                if(len[p]+1==len[q]) link[np] = q;
                else{
                    int clone = ++tot;
                    link[clone] = link[q];
                    ch[clone] = ch[q];
                    len[clone] = len[p] + 1;
                    while(p!=-1 and ch[p].count(x) and ch[p].at(x)==q){
                        ch[p].at(x) = clone;
                        p = link[p];
                    }
                    link[q] = link[np] = clone;
                }
            }
            last = np;
        }
        void minimal_circle(){
            int u = 0;
            for(int i = 1; i <= n; i++){
                printf("%d ",ch[u].begin()->first);
                u = ch[u].begin()->second;
            }
        }
    }sam;
    int main(){
        scanf("%d",&n);
        for(int i = 1; i <= n; i++) scanf("%d",&A[i]);
        for(int i = 1; i <= n; i++) sam.extend(A[i]);
        for(int i = 1; i <= n; i++) sam.extend(A[i]);
        sam.minimal_circle();
        return 0;
    }
    
  • 相关阅读:
    seajs加载angularjs
    seajs加载jquery提示$ is not a function
    java 动态代理
    C#第三章--对象和类
    Android笔记--两种双击退出程序的方法
    Android--Volley基本用法及自定义
    Win10专业版只要12.99元?应用商店Bug福利也算数
    新人报道
    排序

  • 原文地址:https://www.cnblogs.com/kikokiko/p/12699048.html
Copyright © 2011-2022 走看看