Codeforces Round #427 (Div. 2) D-Palindromic characteristics (回文串,暴力)

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.

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.

题目大意

 找回文串,一个k阶回文串的定义是他的左边一半是一个k-1阶回文串。输出1-|s|阶回文串的个数。

注意题目要求,一个k阶回文串也会在k-1阶里面计数,但这问题不大。

首先用通用技巧,在每两个字符之间增加一个字符,来避免讨论奇偶。
然后为了方便的判断阶数,我们可以暴力的开一个数组,来记录以L为起点以R为终点的字符串的阶数,非回文串为0,于是我们只需要枚举中间数,向两边拓展,然后阶数就等于一边的阶数加一即可。注意不要把前面增加的字符算进来。具体可以参见代码。

代码:

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<cstring>
#define ll long long
using namespace std;
ll cnt[12345],i,j,k,l,p,x,y,tmp,n;
string s;
char A[12345];
short Q[10005][10005];
int main()
{
    cin>>s;n=s.length();s=" "+s;
    for(i=1;i<=n;i++)
    {
        A[2*i-1]=s[i];
        A[2*i]='#';
    }
    cnt[1]+=n;
    n=2*n-1;
    for(i=1;i<=n;i++)
    if(A[i]!='#')Q[i][i]=1;
    for(k=1;k<=n;k++)
    {
        for(l=1;k-l>=1&&k+l<=n;l++)
        {
            if(A[k-l]=='#')continue;
            i=k-l;j=k+l;
            if(A[i]!=A[j])break;
            if(A[k-1]=='#')x=k-2;
            else x=k-1;
            tmp=Q[i][x]+1;
            cnt[tmp]++;
            Q[i][j]=tmp;
        }
    }
    for(i=s.length()-1;i>0;i--)cnt[i]+=cnt[i+1];
    for(i=1;i<s.length();i++)printf("%I64d ",cnt[i]);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值