http://codeforces.com/contest/245/problem/H
题意:给定一个字符串,每次给个区间,求区间内有几个回文串(n<=5000)
思路:设定pd[i][j]代表i~j这部分是不是一个回文串,这个可以n^2预处理
然后设定f[i][j]代表i~j区间有多少个回文串,由于满足区间加减,因此有
f[i][j]=f[i+1][j]+f[i][j-1]-f[i+1][j-1]+pd[i][j]
1 #include<cstdio> 2 #include<cmath> 3 #include<algorithm> 4 #include<cstring> 5 #include<iostream> 6 int pd[5005][5005],f[5005][5005],n; 7 char s[20005]; 8 int read(){ 9 int t=0,f=1;char ch=getchar(); 10 while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();} 11 while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();} 12 return t*f; 13 } 14 void init(){ 15 for (int i=1;i<=n;i++) 16 pd[i][i]=1; 17 for (int len=2;len<=n;len++) 18 for (int i=1;i+len-1<=n;i++){ 19 int j=i+len-1; 20 if (i==j-1&&s[i]==s[j]) pd[i][j]=1; 21 else 22 if (s[i]==s[j]) pd[i][j]|=pd[i+1][j-1]; 23 } 24 for (int i=1;i<=n;i++) 25 f[i][i]=1; 26 for (int i=1;i<n;i++) 27 if (s[i]==s[i+1]) 28 f[i][i+1]=3; 29 else 30 f[i][i+1]=2; 31 for (int len=3;len<=n;len++) 32 for (int i=1;i+len-1<=n;i++){ 33 int j=i+len-1; 34 f[i][j]=f[i+1][j]+f[i][j-1]-f[i+1][j-1]+pd[i][j]; 35 } 36 } 37 int main(){ 38 scanf("%s",s+1); 39 n=strlen(s+1); 40 init(); 41 int T=read(); 42 while (T--){ 43 int l=read(),r=read(); 44 printf("%d ",f[l][r]); 45 } 46 return 0; 47 }