最小表示法
参考:最小表示法
目的:O(n)求出一个序列循环同构中最小的那一个(在字符串中表示为字典序最小的一个循环同构)
优化内容:i,j 分别是当前比较的起始下标,k 是已比较的个数。当前假设(A_{i+k}>B_{j+k}),那么对于(i+p(ile i+ple i+k))起始的字符串,(S_{j+p})一定比它更优,所以这一段可以直接跳过。
#include<bits/stdc++.h>
using namespace std;
const int maxn=3e5+5;
int a[maxn];
int main(){
int n;cin>>n;
for(int i=0;i<n;++i) cin>>a[i];
int k=0,i=0,j=1;
while(k<n&&i<n&&j<n){
if(a[(i+k)%n]==a[(j+k)%n]) k++;
else{
if(a[(i+k)%n]>a[(j+k)%n]) i+=k+1;
else j+=k+1;
if(i==j) ++i;
k=0;
}
}
int op=min(i,j);
for(i=0;i<n;++i)
cout<<a[(op+i)%n]<<"
"[i==n-1];
}