最小表示法

最小表示法

参考:最小表示法

目的: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];
}
原文地址:https://www.cnblogs.com/CADCADCAD/p/13513076.html