首先马拉车一遍(或者用hash),再做个前缀和处理出f[i][j]表示以j为右端点,左端点在[i,j]的回文串个数
然后设ans[i][j]是[i,j]之间的回文串个数,那就有ans[i][j]=ans[i][j-1]+f[i][j]
1 #include<bits/stdc++.h> 2 #define pa pair<int,int> 3 #define CLR(a,x) memset(a,x,sizeof(a)) 4 using namespace std; 5 typedef long long ll; 6 const int maxn=5005; 7 8 inline ll rd(){ 9 ll x=0;char c=getchar();int neg=1; 10 while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();} 11 while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar(); 12 return x*neg; 13 } 14 15 int rad[maxn<<1],N,Q,ans[maxn][maxn]; 16 int f[maxn][maxn]; 17 char s[maxn<<1]; 18 19 int main(){ 20 int i,j,k; 21 scanf("%s",s+1);N=strlen(s+1); 22 for(i=N;i;i--){ 23 s[i<<1]=s[i];s[i<<1|1]='#'; 24 }s[1]='#',s[0]='!'; 25 int a=0,p=0; 26 for(i=1;i<=(N<<1|1);i++){ 27 rad[i]=p>=i?min(p-i+1,rad[2*a-i]):1; 28 while(s[i+rad[i]]==s[i-rad[i]]) rad[i]++; 29 if(i+rad[i]-1>p) p=i+rad[i]-1,a=i; 30 for(j=1;j<=rad[i];j++){ 31 if(s[i+j-1]!='#') f[(i-j+1)>>1][(i+j-1)>>1]=1; 32 } 33 } 34 for(i=1;i<=N;i++){ 35 for(j=i;j;j--) f[j][i]+=f[j+1][i]; 36 } 37 for(i=1;i<=N;i++){ 38 for(j=i;j<=N;j++){ 39 ans[i][j]=ans[i][j-1]+f[i][j]; 40 } 41 } 42 Q=rd(); 43 for(i=1;i<=Q;i++){ 44 int a=rd(),b=rd(); 45 printf("%d ",ans[a][b]); 46 } 47 return 0; 48 }