2 4 abab 4 aaab
2 0 4 0
方法:倍长字符串长度,构建后缀数组。
注意:顺时针时在字符串末尾补0(无穷小);逆时针时在字符串末尾补'z'+1(无穷大).
#include <map> #include <set> #include <stack> #include <queue> #include <cmath> #include <ctime> #include <vector> #include <cstdio> #include <cctype> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> using namespace std; #define INF 0x3f3f3f3f #define inf -0x3f3f3f3f #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define mem0(a) memset(a,0,sizeof(a)) #define mem1(a) memset(a,-1,sizeof(a)) #define mem(a, b) memset(a, b, sizeof(a)) typedef long long ll; const int maxn=40000+100; char s[maxn],s1[maxn],s2[maxn]; char s3[maxn],s4[maxn]; int rank1[maxn]; int sa[maxn],t[maxn],t2[maxn],c[maxn],n; //构造字符串s的后缀数组,每个字符值必须为0~m-1 void build_sa(int m){ int *x=t,*y=t2; //基数排序 for(int i=0;i<m;i++) c[i]=0; for(int i=0;i<n;i++) c[x[i]=s[i]]++; for(int i=1;i<m;i++) c[i]+=c[i-1]; for(int i=n-1;i>=0;i--) sa[--c[x[i]]]=i; for(int k=1;k<=n;k<<=1){ int p=0; //直接利用sa数组排序第二关键字 for(int i=n-k;i<n;i++) y[p++]=i; for(int i=0;i<n;i++) if(sa[i]>=k) y[p++]=sa[i]-k; //基数排序第一关键字 for(int i=0;i<m;i++) c[i]=0; for(int i=0;i<n;i++) c[x[y[i]]]++; for(int i=1;i<m;i++) c[i]+=c[i-1]; for(int i=n-1;i>=0;i--) sa[--c[x[y[i]]]]=y[i]; //根据sa和y计算新的x数组 swap(x,y); p=1; x[sa[0]]=0; for(int i=1;i<n;i++) x[sa[i]]=y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+k]==y[sa[i]+k]?p-1:p++; if(p>=n) break; m=p; //下次基数排序的最大值 } for(int i=0;i<n;i++) rank1[i]=x[i]; } int main(){ int t; //freopen("5442.in","r",stdin); scanf("%d",&t); while(t--){ scanf("%d",&n); int m=n; scanf("%s",s); for(int i=0;i<n;i++) s[i+n]=s[i]; s[2*n]='0'; n=n*2+1; build_sa(240); int x,y; x=0; for(int i=1;i<m;i++) if(rank1[i]>rank1[x]) x=i; strcpy(s2,s); int cnt=0; for(int i=n-2;i>=0;i--) s[cnt++]=s2[i]; s[cnt]=char('z'+1); build_sa(240); y=m-1; for(int i=m-2;i>=0;i--) if(rank1[i]>rank1[y]) y=i; int z=y; y=m-1-y; cnt=0; for(int i=x;;i++){ s3[cnt++]=s2[i]; if(cnt>=m) break; } s3[cnt]='\0'; cnt=0; for(int i=z;;i++){ s4[cnt++]=s[i]; if(cnt>=m) break; } s4[cnt]='\0'; if(strcmp(s3,s4)==0){ if(x<=y) printf("%d 0\n",x+1); else printf("%d 1\n",y+1); } else if(strcmp(s3,s4)<0) printf("%d 1\n",y+1); else printf("%d 0\n",x+1); } return 0; }