【模板】最小表示法

字符串的最小表示是该字符串的所有循环同构串中字典序最小的那个串。

根据其循环同构结构,采用破环成链,即:倍增的形式来表示。

引理:若两个循环同构串\(s[i+k]<s[j+k]\),则对于任意的\(i\in[i,i+k]\),均不可能是最优解。
证明:\(s[i+k]<s[j+k]\),所以对任意的\(i'\in[i,i+k]\),有串\(s[j'+p]<s[i'+p]\),其中\(i'+p=j'+p=i+k=j+k\),证毕。

代码如下

#include <bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;

char s[maxn];
int n;

void read_and_parse(){
	scanf("%s",s+1);
	n=strlen(s+1);
	for(int i=1;i<=n;i++)s[i+n]=s[i];
}

void solve(){
	int i=1,j=2,k;
	while(i<=n&&j<=n){
		for(k=0;k<=n&&s[i+k]==s[j+k];k++);
		if(k==n)break;
		if(s[i+k]>s[j+k]){
			i=i+k+1;
			if(i==j)++i;
		}else{
			j=j+k+1;
			if(i==j)++j;
		}
	}
	printf("%d\n",min(i,j));
}

int main(){
	read_and_parse();
	solve();
	return 0;
}
posted @ 2018-10-27 21:02  shellpicker  阅读(153)  评论(0编辑  收藏  举报