最小表示法

最小表示法

O(n)找到字典序最小的循环串

做法

先把串复制一遍,维护指针ij表示[0,max(i,j)-1]中除min(i,j)均不合法,再维护匹配了k位

(此时min(i,j)不一定合法,但这样的话min(i,j)一定会跳到和另一个交换为止,则另一个会变为新的min,这样就合法了)

直接顺序匹配s[i+k],s[j+k],若s[i+k]>s[j+k]则显然[i,i+k]均不合法(因为[j,j+k]对应更优),所以i->i+k+1

当i>=n/j>=n就结束,此时只剩一个合法串

注意有i=j的时候,此时若s[i+1]<s[i]则+1,否则把i+1->j(即右移到能放指针j为止)

code

洛谷模板

i=0,j=1,k=0;
while (i<n && j<n && k<n)
{
	if (a[i+k]==a[j+k]) ++k;
	else
	{
		if (a[i+k]>a[j+k]) i=i+k+1;
		else j=j+k+1;
		k=0;
	}
	if (i==j)
	{
		while (i+1<n && a[i]>a[i+1]) ++i,++j;
		++j;
	}
}
posted @ 2021-02-04 15:09  gmh77  阅读(96)  评论(0编辑  收藏  举报