Codeforces Round #427 (Div. 2) D. Palindromic characteristics
Palindromic characteristics of string s with length |s| is a sequence of |s| integers, where k-th number is the total number of non-empty substrings of s which are k-palindromes.
A string is 1-palindrome if and only if it reads the same backward as forward.
A string is k-palindrome (k > 1) if and only if:
- Its left half equals to its right half.
- Its left and right halfs are non-empty (k - 1)-palindromes.
The left half of string t is its prefix of length ⌊|t| / 2⌋, and right half — the suffix of the same length. ⌊|t| / 2⌋ denotes the length of string t divided by 2, rounded down.
Note that each substring is counted as many times as it appears in the string. For example, in the string "aaa" the substring "a" appears 3 times.
The first line contains the string s (1 ≤ |s| ≤ 5000) consisting of lowercase English letters.
Print |s| integers — palindromic characteristics of string s.
abba
6 1 0 0
abacaba
12 4 1 0 0 0 0
In the first example 1-palindromes are substring «a», «b», «b», «a», «bb», «abba», the substring «bb» is 2-palindrome. There are no 3- and 4-palindromes here.
给定一个字符串,求1-len阶回文串,k阶回文串的左边是有k-1阶回文串组成的,1阶回文串就是字符串的每一个子串回文串。
用dp来做,dp[i][j]表示字符串str[i...j]是否是回文串。O(n^2)的复杂度。
然后求dp[i][j]是第几阶回文串,可以用递归来做,如果str[i..j]不是回文串的话,则返回0,否则返回str[i...m]+1,m表示子串str[i....j]的左串的右边位置。i==j,在递归会出现m<l的因为,返回0;
只好可以把1阶回文串的左边看成由0阶回文串组成的。由于k阶回文串又是k-1,k-2...1阶会文串,所以要ans[i-1] += ans[i]
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int MAX = 5010; 4 char str[MAX]; 5 int dp[MAX][MAX], ans[MAX], n; 6 int getK(int l, int r) { 7 if(dp[l][r] == 0) return 0; 8 else { 9 int m = (l+r); 10 if(m&1) return getK(l,m/2)+1; 11 else return getK(l,m/2-1)+1; 12 } 13 } 14 int main() { 15 scanf("%s",str+1); 16 int n = strlen(str+1); 17 for(int i = 1; i <= n; i ++) { 18 dp[i][i] = 1; 19 if(i+1 <= n && str[i] == str[i+1]) dp[i][i+1] = 1; 20 } 21 for(int i = 3; i <= n; i ++) { 22 for(int j = 1; j <= n-i+1; j ++) { 23 int r = j+i-1; 24 if(dp[j+1][r-1] && str[j] == str[r]) dp[j][r] = 1; 25 } 26 } 27 for(int i = 1; i <= n; i ++) { 28 for(int j = i; j <= n; j ++) { 29 ans[getK(i,j)] ++; 30 } 31 } 32 for(int i = n; i > 0; i --) 33 ans[i-1] += ans[i]; 34 for(int i = 1; i <= n; i ++) 35 printf("%d%c",ans[i],(i==n?'\n':' ')); 36 return 0; 37 }