HDU5442
HDU5442
做法:把原串复制一份加在后边,中间插特殊入个特殊字符,再把翻转后的串加在后边,同样复制一份。然后做后缀数组,按题意处理细节即可。
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <map>
#include <cstring>
#include <cmath>
#include <queue>
#include <set>
#include <vector>
#include <iterator>
#include <string>
#include <deque>
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define per(i,a,b) for(int i=a;i>=b;--i)
#define pb push_back
#define MP make_pair
#define fr first
#define sc second
#define PII pair<int,int>
#define VI vector<int>
typedef long long ll;
typedef unsigned long long ull;
const int N = 100005;
inline int readint() {
char c=getchar();int x=0,f=1;
while(!isdigit(c)){if(f=='-')f=-1;c=getchar();}
while(isdigit(c)){x=x*10+c-'0';c=getchar();}
return x*f;
}
using namespace std;
int n;
char c[N],str[N];
int rnk[N] , SA[N] , Height[N];
int X[N] , Y[N] , sum[N];
int f[101000][20] , fm[101000][20];
bool cmp(int *r,int a,int b,int l) {
return ( r[a] == r[b] && r[a+l] == r[b+l] );
}
void calc() {
int l , p , *x = X , *y = Y , m = 128;
rep(i,0,m) sum[i] = 0;
rep(i,1,n) sum[ x[i] = c[i] ] ++;
rep(i,1,m) sum[i] += sum[i-1];
per(i,n,1) SA[ sum[ x[i] ]-- ] = i;
for ( l = 1 , p = 1 ; l <= n ; m = p , l *= 2 ) {
p = 0;
rep(i,n-l+1,n) y[++p] = i;
rep(i,1,n) if ( SA[i] > l ) y[++p] = SA[i] - l;
rep(i,0,m) sum[i] = 0;
rep(i,1,n) sum[ x[y[i]] ] ++;
rep(i,1,m) sum[i] += sum[i-1];
per(i,n,1) SA[ sum[ x[y[i]] ]-- ] = y[i];
swap( x , y );
x[SA[1]] = 1; p = 2;
rep(i,2,n)
x[ SA[i] ] = cmp(y,SA[i-1],SA[i],l) ? p - 1 : p++;
}
rep(i,1,n) rnk[SA[i]] = i;
p = 0;
rep(i,1,n) {
if ( rnk[i] == 1 ) continue;
while ( c[i+p] == c[SA[rnk[i]-1]+p] ) p ++;
Height[rnk[i]] = p;
if ( p ) p --;
}
}
void init() {
n = strlen(str);
int cc = 0;
for(int i=0;i<n;++i) c[++cc] = str[i];
for(int i=0;i<n;++i) c[++cc] = str[i];
c[++cc] = '$';
for(int i=n-1;i>=0;--i) c[++cc] = str[i];
for(int i=n-1;i>=0;--i) c[++cc] = str[i];
c[cc+1]=0;
n = cc;
}
int Log[N],rmq[N][30];
void init_rmq() {
Log[1] = 0;
for(int i=2;i<=n;++i) Log[i] = Log[i>>1] + 1;
for(int i=1;i<=n;++i) rmq[i][0] = Height[i];
for(int j=1;j<=20;++j)
for(int i=1;i+(1<<(j-1))<=n;++i)
rmq[i][j] = min(rmq[i][j-1],rmq[i+(1<<j-1)][j-1]);
}
int RMQ_mn(int l,int r){
int L=Log[r-l+1];
return min(rmq[l][L],rmq[r-(1<<L)+1][L]);
}
int ask(int x,int y) {
x=rnk[x],y=rnk[y];
if(x>y)swap(x,y);
return RMQ_mn(x+1,y);
}
int T, num;
int biao(int x) {
if(x <= num) return x;
return num - (x-num*2-1) + 1;
}
int cal_s(int x) {
if(x<=num) return 0;
return 1;
}
int main() {
scanf("%d",&T);
while(T--) {
scanf("%d",&num);
scanf(" %s",str);
init();
calc();
init_rmq();
int idx = n;
int ansb = biao(SA[n]), anss = cal_s(SA[n]);
for(int i=n;i>=1;--i) if(SA[i]!=num*2+1){
if(SA[i]<=num) {
idx = i;
ansb = biao(SA[i]);
anss = cal_s(SA[i]);
break;
}
if(SA[i]>=2*num+1&&SA[i]<=3*num+1) {
idx = i;
ansb = biao(SA[i]);
anss = cal_s(SA[i]);
break;
}
}
for(int i=idx-1;i>=1;--i) if(SA[i] != num*2+1) {
if(SA[i]>num&&SA[i]<=num*2+1) continue;
if(SA[i]>3*num+1) continue;
int lcp = ask(SA[idx],SA[i]);
if(lcp >= num) {
int b = biao(SA[i]), s = cal_s(SA[i]);
if(b<ansb) ansb = b,anss=s;
else if(b==ansb&&s < anss) ansb=b,anss=s;
}
}
printf("%d %d\n",ansb,anss);
}
return 0;
}