直接采用最小字典表示法,在处理逆序的时候,如果存在循环节,则需要根据周期找到最大的ID
ACCode:
#include<set>
#include<map>
#include<cmath>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long LL;
const int NS=200100;
const double eps=1e-8;
const int MOD=1000000007;
char ch[NS];
char uh[NS];
int n;
int mysearch(int len, char* str)
{
int i=0,j=1,k=0,t;
while(i<len&&j<len && k <= len)
{
t=str[(i+k)%len]-str[(j+k)%len];
if(!t) k++;
else if (t>0) j+=k+1,k=0;
else i+=k+1,k=0;
if(i==j) j++;
// printf("i = %d j = %d k = %d\n", i,j,k);
}
if(i >= len)
{
return j;
}
if(j >= len)
{
return i;
}
return min(i, j);
}
int unsearch(int len, char* str)
{
int i=0,j=1,k=0,t;
while(i<len&&j<len && k <= len)
{
t=str[(i+k)%len]-str[(j+k)%len];
if(!t) k++;
else if (t>0) j+=k+1,k=0;
else i+=k+1,k=0;
if(i==j) j++;
// printf("i = %d j = %d k = %d\n", i,j,k);
}
if(i >= len)
{
return j;
}
if(j >= len)
{
return i;
}
int T = max(i, j) - min(i, j);
int res = max(i, j);
while(res + T < len)
{
res += T;
}
return res;
}
int main()
{
int nCase;
scanf("%d", &nCase);
while(nCase --)
{
scanf("%d", &n);
scanf("%s", ch);
ch[n + n] = '\0';
uh[n + n] = '\0';
for(int i = 0; i < n; i++)
{
ch[i + n] = ch[i];
uh[i] = ch[n - i - 1];
uh[i + n] = uh[i];
}
int cSt = mysearch(n, ch);
int uSt = unsearch(n, uh);
int uRt = n - 1 - uSt;
// printf("cSt=%d uSt=%d uRt=%d\n", cSt, uSt, uRt);
int res = 0;
for(int i = 0; i < n; i++)
{
if(ch[i + cSt] > uh[i + uSt])
{
res = 1;
break;
}
else if(ch[i + cSt] < uh[i + uSt])
{
res = 2;
break;
}
}
if(0 == res)
{
if(cSt <= uRt)
{
printf("%d %d\n", cSt + 1, 0);
}
else
{
printf("%d %d\n", uRt + 1, 1);
}
}
else if(1 == res)
{
printf("%d %d\n", cSt + 1, 0);
}
else
{
printf("%d %d\n", uRt + 1, 1);
}
}
return 0;
}