Codeforces 835D

来源:互联网 发布:java int转char数组 编辑:程序博客网 时间:2024/06/09 22:53


D. Palindromic characteristics


time limit per test 3seconds

memory limit per test     256megabytes


Palindromic characteristics of strings with length |s| is a sequence of |s| integers, where k-th number is the total number ofnon-empty substrings of s which are k-palindromes.

A string is1-palindrome if and only if it reads the same backward asforward.

A string isk-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 stringt is its prefix of length |t| / 2, and right half — thesuffix of the same length. |t| / 2denotes the length of string t divided by 2, rounded down.

Note that each substring is counted as many times as it appearsin the string. For example, in the string "aaa" the substring"a" appears 3 times.

Input

The first line contains the strings (1 ≤ |s| ≤ 5000) consisting oflowercase 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.

 



【题意】

给出一个字符串,问它分别具有多少个k级字符串。


一个回文串叫做1级回文串,一个回文串为k级回文串当且仅当它的左半部分和右半部分相同,且两部分都是(k-1)级回文串。


【思路】


显然我们发现k级字符串的得到需要(k-1)级字符串的铺垫,那么就知道可以用区间DP来解决这个问题。


我们用dp[i][j]来表示s[i]~s[j] 这一段字符串是几级回文串,如果它是一个回文串,那么在s[i-1]==s[j+1]的情况下,s[i-1]~s[j+1]就是回文串了,且其级数为前一个回文串左边一半的级数+1.


dp[i-1][j+1]=dp[i][(i+j)/2]+1.


有了这个状态转移方程基本就大功告成了。


#include <cstdio>#include <vector>#include <cstring>#include <algorithm>using namespace std;#define mst(a,b) memset((a),(b),sizeof(a))#define rush() int T;scanf("%d",&T);while(T--)typedef long long  ll;const int maxn = 5005;const ll mod = 1e9+7;const int INF = 0x3f3f3f;const double eps = 1e-9;ll dp[maxn][maxn];               //s[i]~s[j]字符串的级数bool flag[maxn][maxn];           //s[i]~s[j]是否为回文串ll ans[maxn]; char s[maxn];int main(){    while(~scanf("%s",s+1))    {        mst(dp,0);        mst(flag,0);        mst(ans,0);        int n=strlen(s+1);        for(int i=1;i<=n;i++)     //预处理        {            dp[i][i]=1;            flag[i][i]=1;        }        for(int len=1;len<=n;len++)        for(int i=1;i<=n;i++)        {            int j=i+len;            if(j>n) continue;            if(s[i]==s[j])            {                if(j-i==1||flag[i+1][j-1])                {                    int m=(i+j)/2;                    if((j-i+1)&1) m--;                    flag[i][j]=1;                    dp[i][j]=dp[i][m]+1;                }            }        }        for(int i=1;i<=n;i++)        for(int j=1;j<=n;j++)        {            ans[dp[i][j]]++;        }        for(int i=n-1;i>=1;i--)        {            ans[i]+=ans[i+1];           //级别高的回文串一定也是级别低的回文串,比如是五级回文串的话,就一定是四(3,2,1)级回文串        }        for(int i=1;i<n;i++)        {            printf("%I64d ",ans[i]);        }        printf("%I64d\n",ans[n]);    }    return 0;}















原创粉丝点击