hdu5422 最大表示法+KMP

#include <iostream>
#include <algorithm>
#include <string.h>
#include <cstdio>
#include <vector>
using namespace std;
const int maxn=20005;
int MaxRepresstation(char * S, int len ) {
      int i = 0, j = 1, k = 0;
      while(i < len && j < len)
        {
            k = 0;
           while(k < len && S[(i + k)%len] == S[(j + k)%len])
            k++;
           if(k >= len)
            break;
           if(S[(i + k)%len] > S[(j + k)%len])
            j = max(i + 1, j + k + 1);
           else
            i = max(i + k + 1, j + 1);
        }
      return min(i ,j);
}
char s[maxn];
char s2[maxn*2];
char s3[maxn];
int F[maxn];
void getFail(char *P, int *f, int m)
{
    f[0]=0;f[1]=0;
    for(int i=1; i<m; i++)
    {
         int j=f[i];
         while(j&&P[i]!=P[j])j=f[j];
         f[i+1]=P[i]==P[j]?j+1:0;
    }
}
int find(char *T, char *P, int *f, int n, int m)
{
    getFail(P,f,m);
     int j=0;
     int ans=0;
     for(int i=0; i<n; i++)
     {
         while(j&&P[j]!=T[i]) j=f[j];
         if(P[j]==T[i])j++;
         if(j==m){
            ans=max(ans,i-m+1);
            j=f[j];
         }
     }
     return ans;
}
int main()
{
    int cas;
    scanf("%d",&cas);
    for(int cc=1; cc<=cas; cc++)
        {
             int n;
             scanf("%d",&n);
             scanf("%s",s);
             int d1=MaxRepresstation(s,n);
             for(int i=0; i<n;i++)
                s2[i]=s[n-1-i];
             int d2=MaxRepresstation(s2,n);
             for(int i=0; i<n; i++)
                {
                    s3[i]=s2[(d2+i)%n];
                    s2[i+n]=s2[i];
                }
             d2=find(s2,s3,F,n*2-1,n);
             d2 = n-1-d2;
             int f=-1,ans=-1;
             for(int i=0; i<n; i++)
                {
                     int x1=(d1+i)%n,x2=(d2-i+n)%n;
                     if(s[x1]==s[x2])continue;
                     if(s[x1]>s[x2]){
                        ans=d1; f=0; break;
                     }else{
                        ans=d2; f=1; break;
                     }
                }
             if(f==-1){
                 if(d1<=d2){
                    ans=d1; f=0;
                 }else{
                    ans=d2; f=1;
                 }
             }
             printf("%d %d
",ans+1,f);
        }

    return 0;
}
原文地址:https://www.cnblogs.com/Opaser/p/4810767.html