定义循环同构串——当字符串S中选定一个位置i满足S[i~n]+S[1-i-1]=T,最小表示发用来找到字符串中最小字典序的循环同构串。
类似KMP的思想。先破环成链,然后三指针比较。重点在于若 \(S[i+k]>S[j+k]\) 则 \(i=i+k+1\),这一点将算法优化了很多。
模板题:
#include <bits/stdc++.h>
using namespace std;
int s[600005], n;
int zxbsf()
{
for (int i = 1; i <= n; i++) {
s[i + n] = s[i];
}
int i = 1, j = 2, k = 0;
while (i <= n && j <= n) {
for (k = 0; k <= n && s[i+ k] == s[j + k]; k++);
s[i + k] > s[j + k] ? i = i + k + 1 : j = j + k + 1;
if (i == j) j ++;
}
return min(i,j);
}
int main()
{
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> s[i];
}
int k = zxbsf();
for (int i = 0; i < n; i++) {
cout << s[i + k] << " ";
} cout << endl;
return 0;
}
每次向后扫描 \(k\) 的长度,则 \(i\) 或 \(j\),最多向后移动 \(2n\) 的长度,所以时间复杂度是 \(O(n)\) 的。
标签:同构,int,最小,表示法,++,zxbsf,小记 From: https://www.cnblogs.com/CYLSY/p/17069663.html