codeforces round#427D Palindromic characteristics

Open the transmission gate

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.

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.

[translation]

Give you a string with a length not exceeding 5000 and ask how many palindrome substrings of order KK are there respectively. The KK-order palindrome substring is defined as follows:

For a string, if it itself is a palindrome string, and its left and right substrings are K_1K_1 palindrome strings, then this substring is K_1K_1 palindrome strings.

[solution]

Apparently dp, the key is how to transfer.

Let's assume that dp[i][j] represents the order of the molecule string from I I to J j, which is easy to obtain.
dp[i][i]=1dp[i][i]=1
dp[i][i+1]=(que[i]==que[i+1]?2:0)dp[i][i+1]=(que[i]==que[i+1]?2:0)
For substrings longer than 2, we just use the previous answer to recurse.
One thing to note is that if a substring is a K-order substring, then obviously it is also a (k-1) order substring, so let's remember to add it up when we count the answers.

[code]

#include <bits/stdc++.h>
using namespace std;
const int maxm = 5e3+10;
char que[maxm];
int dp[maxm][maxm];
int ans[maxm];
int main() {
    //freopen("C:\\Users\\ACM2018\\Desktop\\in.txt","r",stdin);
    scanf("%s",que);
    int len = strlen(que);
    for(int i = 0;i<len;i++){/// Enumeration length
        for(int l = 0;l+i<len;l++){/// Enumerate a left node
            if(i==0) dp[l][l+i] = 1;/// The length of 1 is palindrome of the first order.
            else if(i==1)/// A palindrome of 2 length may be non-palindrome or second-order palindrome.
                dp[l][i+l] = (que[l]==que[l+1]?2:0);
            else if(que[l]==que[i+l]&&dp[l+1][l+i-1]){/// First of all, ensure that this substring palindrome
                dp[l][l+i] = 1;
                int mid = (l+l+i)>>1;
                if(i&1){
                    if(dp[l][mid]&&dp[mid+1][l+i]){
                        dp[l][l+i] = dp[l][mid]+1;
                    }
                }
                else {
                    if(dp[l][mid-1]&&dp[mid+1][l+i]){
                        dp[l][l+i] = dp[l][mid-1]+1;
                    }
                }
            }
        }
    }
    for(int i = 0;i<len;i++){
        for(int j = i;j<len;j++){
            ans[dp[i][j]]++;
        }
    }
    for(int i = len-1;i>=0;i--){
        ans[i]+=ans[i+1];
    }
    for(int i = 1;i<=len;i++){
        printf("%d ",ans[i]);
    }
    return 0;
}

Posted by portrower8 on Tue, 05 Feb 2019 08:42:17 -0800