F01【模板】最小表示法
题目:给定一个字符串 s,求出 s 的最小表示(字典序最小的循环同构串)。
例:caacabcaab → aabcaacabc
// 最小表示法 O(n) #include<bits/stdc++.h> using namespace std; const int N=2e7+5; int n; char s[N]; int get_min(){ 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>>s+1; for(int i=1;i<=n;i++) s[n+i]=s[i]; int k=get_min(); for(int i=0;i<n;i++) printf("%c",s[k+i]); return 0; }
// 最小表示法 O(n) #include<bits/stdc++.h> using namespace std; const int N=7e5; int n,s[N]; int get_min(){ for(int i=1;i<=n;i++) s[n+i]=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(){ scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&s[i]); int k=get_min(); for(int i=0;i<n;i++) printf("%d ",s[k+i]); return 0; }
浙公网安备 33010602011771号