CF245H Queries for Number of Palindromes

题目链接

Description:

You've got a string s = s1s2... s|s| of length |s|, consisting of lowercase English letters. There also are q queries, each query is described by two integers li, ri (1 ≤ li ≤ ri ≤ |s|). The answer to the query is the number of substrings of string s[li... ri], which are palindromes.
String s[l... r] = slsl + 1... sr (1 ≤ l ≤ r ≤ |s|) is a substring of string s = s1s2... s|s|.
String t is called a palindrome, if it reads the same from left to right and from right to left. Formally, if t = t1t2... t|t| = t|t|t|t| - 1... t1.

#include<cstdio>
#include<cstring>
using namespace std;
const int L = 5010;
char s[L];
int dp[L][L],flag[L][L],q,len;
int C(int l,int r)
{
	if(flag[l][r]) return 1;
	return flag[l][r] = (s[l] == s[r])&&C(l + 1,r - 1);
}
int rec(int l,int r)
{
	if(dp[l][r]) return dp[l][r];
	if(l == r) return dp[l][r] = 1;
	if(l == r - 1) return dp[l][r] = 2 + (s[l] == s[r]? 1 : 0);
	return dp[l][r] = rec(l,r - 1) + rec(l + 1,r) - rec(l + 1,r - 1) + C(l,r);
}
void solve()
{
	len = strlen(s + 1);
	for(int i = 1;i <= len;++i)
	{
		dp[i][i] = flag[i][i] = 1;
		if(s[i] == s[i+1]){
			dp[i][i + 1] = 3;
			flag[i][i + 1] = 1;
		}
		else
		{
			dp[i][i + 1] = 2;	
			flag[i][i + 1] = 0;
		}
	}
	for(int k = 3;k <= len;++k)
	{
		int l = 1;
		for(int r = k;r <= len;++r,++l)
		{
			dp[l][r] = dp[l][r - 1] + dp[l + 1][r] - dp[l + 1][r - 1] + C(l,r);
		}
	}
}
int main()
{
	scanf("%s",s + 1);
	scanf("%d",&q);
	solve();
	while(q--)
	{
		int l,r;
		scanf("%d%d",&l,&r);
		printf("%d
",dp[l][r]);
	}
	return 0;
}

参考

岂能尽如人意,但求无愧我心
原文地址:https://www.cnblogs.com/Zforw/p/10957696.html