codeforces835D(94/600)

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.

水题没啥好说的啊…
标记一波按照题意模拟

#include<bits/stdc++.h>
using namespace std;
int dp[5001][5001];
int dan[5001];
int main()
{
    string q;
    cin>>q;
    int k=q.size();
    for(int a=0;a<k;a++)dp[a][a]=1;
    dan[1]=k;
    for(int a=0;a<k;a++)
    {
        for(int b=a-1;b>=0;b--)
        {
            if(q[a]!=q[b])continue;
            int cd=a-b+1;
            if(cd==2)
            {
                dp[b][a]=2,dan[2]++;                
                continue;
            }
            if(!dp[b+1][a-1])continue;
            if(cd%2)
            {
                int zhong=cd/2;
                zhong+=b;
                dp[b][a]=dp[b][zhong-1]+1;
                dan[dp[b][a]]++;
            }
            else
            {
                int zhong=cd/2;
                zhong+=b;
                zhong--;
                dp[b][a]=dp[b][zhong]+1;
                dan[dp[b][a]]++;
            }
        }
    }
    for(int a=k-1;a>=1;a--)dan[a]+=dan[a+1];
    for(int a=1;a<=k;a++)cout<<dan[a]<<" ";
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值