询问区间的最长回文

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>

using namespace std;

const int maxn=200100;

int rad[maxn*2];
char str[maxn],s[maxn*2];
int q;
int odd[maxn],even[maxn];
int mm[maxn],mo[maxn][20],me[maxn][20];
void Manacher(int rad[],char str[],int n){
    int i,mx=0,id;
    for(i=1;i<n;i++){
        if(mx>i) rad[i]=min(rad[2*id-i],mx-i);
        else rad[i]=0;
        for(;str[i+rad[i]]==str[i-rad[i]];rad[i]++)
            ;
        rad[i]--;
        if(mx<rad[i]+i){
            mx=rad[i]+i;
            id=i;
        }
    }
}
void init(){
    int i;
    mm[0]=-1;
    for(i=1;i<maxn;i++)
        mm[i]=((i&(i-1))==0)?mm[i-1]+1:mm[i-1];
}
void cal_RMQ(int n){
    int i,j,k;
    for(i=1;i<=n;i++){
        mo[i][0]=odd[i];
        me[i][0]=even[i];
    }
    for(i=1;i<=mm[n];i++){
        for(j=1;j-1+(1<<i)<=n;j++){
            mo[j][i]=max(mo[j][i-1],mo[j+(1<<(i-1))][i-1]);
            me[j][i]=max(me[j][i-1],me[j+(1<<(i-1))][i-1]);
        }
    }
}
int get_RMQ_odd(int x,int y){
    int k=mm[y-x+1];
    return max(mo[x][k],mo[y-(1<<k)+1][k]);
}
int get_RMQ_even(int x,int y){
    int k=mm[y-x+1];
    return max(me[x][k],me[y-(1<<k)+1][k]);
}
int main(){
    int i,j,n,t,T;
    scanf("%d",&T);
    init();
    for(t=1;t<=T;t++){
        scanf("%s",&str[1]);
        int len=strlen(&str[1]);
        s[0]='$';
        for(i=1;i<=len;i++){
            s[2*i-1]='#';
            s[2*i]=str[i];
        }
        s[2*len+1]='#';
        s[2*len+2]='@';
        Manacher(rad,s,2*len+2);

        for(i=2;i<=2*len+1;i+=2){
            odd[i/2]=rad[i];
            even[i/2]=rad[i+1];
        }
        cal_RMQ(len);

        scanf("%d",&q);
        for(i=1;i<=q;i++){
            int x,y,ans=1;
            int h,l,mid;
            scanf("%d %d",&x,&y);
            l=1,h=(y-x)/2;
            while(l<=h){
                int mid=(l+h)>>1;
                if(get_RMQ_odd(x+mid,y-mid)>=2*mid+1){
                    l=mid+1;
                    ans=max(ans,2*mid+1);
                }
                else
                    h=mid-1;
            }

            l=1,h=(y-x+1)/2;
            while(l<=h){
                int mid=(l+h)>>1;
                if(get_RMQ_even(x+mid-1,y-mid)>=2*mid){
                    l=mid+1;
                    ans=max(ans,2*mid);
                }
                else
                    h=mid-1;
            }
            printf("%d\n",ans);
        }
    }
    return 0;
}