题意:给出一个字符串s(n<=10000000),求他的最小表示法
一开始发现SA或者SAM可以做好像,然而n<=1000w,word哥还是搞最小表示法把。。
最小表示法其实就是一个字符串的最小字典序循环同构的串。
可能你还是很懵比,好举个例子。
设S=bcda,那么S的循环同构串就是cdab,dabc,abdc,他的最小表示法就是abdc.
其实就是要找的一个i的位置,从这个i开始把S断掉,然后输出的就是abdc。
怎么找这个i呢?
我们可以先来想想暴力打法(dalao请跳过)
一开始暴力肯定就是双指针嘛,设i=0,j=1,
然后就有:
i=0,j=1;
while (i
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define N 10000005
using namespace std;
int n;
unsigned char s[N*2];
int main()
{
freopen("2176.in","r",stdin);//freopen("test.out","w",stdout);
scanf("%d",&n);
scanf("%s",s+1);
for (int i=n+1;i<=n*2;i++)
s[i]=s[i-n];
int i=1,j=2;
while (i<n&&j<n)
{
int k=0;
while (s[i+k]==s[j+k]&&k<n) k++;
if (k==n) break;
if (s[i+k]<s[j+k]) j=max(j+k+1,i+1);
else i=max(i+k+1,j+1);
}
i=min(i,j);
for (int k=1;k<=n;k++)
putchar(s[k+i-1]);
return 0;
}

本文介绍了一种求解字符串最小表示法的高效算法。通过寻找特定位置i,将原字符串断开并重新连接得到最小字典序的循环同构串。文章提供了详细的算法思路及C++实现代码。
484

被折叠的 条评论
为什么被折叠?



