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;
}