最小表示法
最小表示法
参考:最小表示法
目的:O(n)求出一个序列循环同构中最小的那一个(在字符串中表示为字典序最小的一个循环同构)
优化内容:i,j 分别是当前比较的起始下标,k 是已比较的个数。当前假设\(A_{i+k}>B_{j+k}\),那么对于\(i+p(i\le i+p\le 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]<<" \n"[i==n-1];
}
CAD加油!欢迎跟我一起讨论学习算法,QQ:1401650042