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:

  1. Its left half equals to its right half.
  2. 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.

Input

The first line contains the string s (1 ≤ |s| ≤ 5000) consisting of lowercase English letters.

Output

Print |s| integers — palindromic characteristics of string s.

Examples
Input
abba
Output
6 1 0 0 
Input
abacaba
Output
12 4 1 0 0 0 0 
Note

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?'
':' '));
36     return 0;
37 }
原文地址:https://www.cnblogs.com/xingkongyihao/p/7270686.html