题目大意
给定一个字符串s,q个查询,每次查询返回s[l…r]含有的回文子串个数(题目地址)
题解
和有一次多校的题目长得好相似,这个是回文子串个数,多校的是回文子序列个数
用dp[i][j]表示,s[i..j]含有的回文子串个数,则dp[i][j]=dp[i][j-1]+dp[i+1][j]-dp[i+1][j-1]+flag[i][j](如果s[i..j]是回文子串则flag[i][j]=1,否则为0)
代码:
#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> using namespace std; #define MAXN 5005 int dp[MAXN][MAXN]; int flag[MAXN][MAXN],n; char s[MAXN]; void solve(int l,int r) { while(l>=1&&r<=n) { if(s[l]==s[r]) { flag[l][r]=1; l--,r++; } else break; } } int main() { while(scanf("%s",s+1)!=EOF) { n=strlen(s+1); memset(dp,0,sizeof(dp)); memset(flag,0,sizeof(flag)); for(int i=1; i<=n; i++) { solve(i,i); solve(i,i+1); } for(int i=1; i<=n; i++) dp[i][i]=1; for(int i=n; i>=1; i--) for(int j=i+1; j<=n; j++) dp[i][j]=dp[i][j-1]+dp[i+1][j]-dp[i+1][j-1]+flag[i][j]; int q; scanf("%d",&q); while(q--) { int l,r; scanf("%d%d",&l,&r); printf("%d ",dp[l][r]); } } return 0; }