最小表示法总结

Posted fexuile

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最小表示法总结相关的知识,希望对你有一定的参考价值。

问题解决

一般用于解决一类最小表示或最小串的问题。

问题引入

例题:poj1509

求它的循环串中字典序最小的串的开头。

问题解决

暴力

找到所有的串存下来然后排序,复杂度\(\Theta(n^2)\)的。

诡异做法

建个后缀自动机然后遍历最小的字母边即可。

正经一点的

考虑两个指针\(i\),\(j\),一边扫过去的时候暴力求一下\(i,j\)\(lcp\)的长度,然后比一下\(lcp\)后一位,把大的那个指针往后移那么多位即可。

代码实现

/*
  mail: mleautomaton@foxmail.com
  author: MLEAutoMaton
  This Code is made by MLEAutoMaton
*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#include<iostream>
using namespace std;
#define ll long long
#define REP(a,b,c) for(int a=b;a<=c;a++)
#define re register
#define file(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout)
inline int gi()
    int f=1,sum=0;char ch=getchar();
    while(ch>'9' || ch<'0')if(ch=='-')f=-1;ch=getchar();
    while(ch>='0' && ch<='9')sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();
    return f*sum;

const int N=100010;
char s[N];int n;
int main()
    int T=gi();
    while(T--)
        scanf("%s",s);n=strlen(s);
        int i=0,j=1;
        while(i<n && j<n)
            int k=0;
            while(k<=n && s[(i+k)%n]==s[(j+k)%n])k++;
            if(k>n)break;
            if(s[(i+k)%n]<=s[(j+k)%n])j=j+k+1;
            else i=i+k+1;
            if(i==j)j=i+1;
        
        printf("%d\n",min(i+1,j+1));
    
    return 0;

以上是关于最小表示法总结的主要内容,如果未能解决你的问题,请参考以下文章

最小生成树次生成树最短路劲0-背包总结

请问,最小正周期指的是啥?在函数图中表示那一段?最好有图片说明

最小表示法(模板)

最小表示法

最大最小表示法

HDU 3374 最小/大表示法+KMP