【CodeForces - 245H 】Queries for Number of Palindromes (带容斥的区间dp)
題干:
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.
Input
The first line contains string?s?(1?≤?|s|?≤?5000). The second line contains a single integer?q?(1?≤?q?≤?106)?— the number of queries. Next?q?lines contain the queries. The?i-th of these lines contains two space-separated integers?li,?ri?(1?≤?li?≤?ri?≤?|s|)?— the description of the?i-th query.
It is guaranteed that the given string consists only of lowercase English letters.
Output
Print?q?integers — the answers to the queries. Print the answers in the order, in which the queries are given in the input. Separate the printed numbers by whitespaces.
Examples
Input
caaaba 5 1 1 1 4 2 3 4 6 4 5Output
1 7 3 4 2Note
Consider the fourth query in the first test case. String?s[4... 6]?= ?aba?. Its palindrome substrings are: ?a?, ?b?, ?a?, ?aba?.
題目大意:
? ?現(xiàn)有一個(gè)字符串?s?=?s1s2...?s|s|?of length?|s|, 由小寫(xiě)字符組成. 現(xiàn)在有?q?次查詢, 每次查詢給兩個(gè)整數(shù)?li,?ri?(1?≤?li?≤?ri?≤?|s|). 每次查詢你的程序要給出此字符串的子串?s[li...?ri]有多少個(gè)回文串.
解題報(bào)告:
? ?顯然是區(qū)間dp,,剛開(kāi)始寫(xiě)搓了,還是區(qū)間dp不太熟練。。
? ?正經(jīng)題解:先處理處長(zhǎng)度為2的來(lái),并且預(yù)處理出任意 l r 子串是否是回文串。然后從len=3開(kāi)始跑區(qū)間dp就行了。
AC代碼:
#include<cstdio> #include<iostream> #include<algorithm> #include<queue> #include<map> #include<vector> #include<set> #include<string> #include<cmath> #include<cstring> #define ll long long #define pb push_back #define pm make_pair #define fi first #define se second using namespace std; const int MAX = 5000 + 5; char s[MAX]; int dp[MAX][MAX]; bool is[MAX][MAX]; int l,r; int main() {cin>>(s+1);int n = strlen(s+1);for(int i = 1; i<=n; i++) dp[i][i] = 1,is[i][i]=1;for(int i = 1; i<=n-2+1; i++) {dp[i][i+1]=2; if(s[i] == s[i+1]) dp[i][i+1]++,is[i][i+1]=1;}for(int len = 3; len<=n; len++) {for(int l = 1; l<=n-len+1; l++) {int r = l+len-1;if(s[l] == s[r]) is[l][r] = is[l+1][r-1];}}for(int len = 3; len<=n; len++) {for(int l = 1; l<=n-len+1; l++) {int r = l+len-1;dp[l][r] = dp[l+1][r] + dp[l][r-1] - dp[l+1][r-1];if(is[l][r]) dp[l][r]++;}}int q;cin>>q;while(q--) {scanf("%d%d",&l,&r);printf("%d\n",dp[l][r]);}return 0 ;}另一個(gè)AC代碼:(好像我寫(xiě)的那個(gè)跑1600ms,,這個(gè)代碼跑200+ms))本來(lái)以為可能是用了按位與,,但是發(fā)現(xiàn)這樣跑出來(lái)也不是很快啊1700+ms。。。可能是數(shù)據(jù)加強(qiáng)了?
#include<cstdio> #include<iostream> #include<algorithm> #include<queue> #include<map> #include<vector> #include<set> #include<string> #include<cmath> #include<cstring> #define ll long long #define pb push_back #define pm make_pair #define fi first #define se second using namespace std; const int MAX = 5000 + 5; char s[MAX]; int dp[MAX][MAX]; bool is[MAX][MAX]; int l,r; int main() {cin>>(s+1);int n = strlen(s+1);for(int i = 1; i<=n; i++) dp[i][i] = 1,is[i][i]=1,is[i+1][i]=1; // for(int i = 1; i<=n-2+1; i++) { // dp[i][i+1]=2; // if(s[i] == s[i+1]) dp[i][i+1]++,is[i][i+1]=1; // }for(int len = 1; len<=n; len++) {for(int j = 1; j<=n; j++) {is[j][j+len] = is[j+1][j+len-1] & (s[j] == s[j+len]);dp[j][j+len] = dp[j][j+len-1] + dp[j+1][j+len] - dp[j+1][j+len-1] + is[j][j+len];}}int q;cin>>q;while(q--) {scanf("%d%d",&l,&r);printf("%d\n",dp[l][r]);}return 0 ;}?
總結(jié)
以上是生活随笔為你收集整理的【CodeForces - 245H 】Queries for Number of Palindromes (带容斥的区间dp)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 买卖银行账户有什么危害?出借银行账户有什
- 下一篇: 信用卡逾期会影响房贷吗 买房一族真的需要