• Codeforces Round #427 (Div. 2) 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:

    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 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.

    给定一个字符串,求1-len阶回文串,k阶回文串的左边是有k-1阶回文串组成的,1阶回文串就是字符串的每一个子串回文串。

    用dp来做,dp[i][j]表示字符串str[i...j]是否是回文串。O(n^2)的复杂度。

    然后求dp[i][j]是第几阶回文串,可以用递归来做,如果str[i..j]不是回文串的话,则返回0,否则返回str[i...m]+1,m表示子串str[i....j]的左串的右边位置。i==j,在递归会出现m<l的因为,返回0;

    只好可以把1阶回文串的左边看成由0阶回文串组成的。由于k阶回文串又是k-1,k-2...1阶会文串,所以要ans[i-1] += ans[i]

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 const int MAX = 5010;
     4 char str[MAX];
     5 int dp[MAX][MAX], ans[MAX], n;
     6 int getK(int l, int r) {
     7     if(dp[l][r] == 0) return 0;
     8     else {
     9         int m = (l+r);
    10         if(m&1) return getK(l,m/2)+1;
    11         else return getK(l,m/2-1)+1;
    12     }
    13 }
    14 int main() {
    15     scanf("%s",str+1);
    16     int n = strlen(str+1);
    17     for(int i = 1; i <= n; i ++) {
    18         dp[i][i] = 1;
    19         if(i+1 <= n && str[i] == str[i+1]) dp[i][i+1] = 1;
    20     }
    21     for(int i = 3; i <= n; i ++) {
    22         for(int j = 1; j <= n-i+1; j ++) {
    23             int r = j+i-1;
    24             if(dp[j+1][r-1] && str[j] == str[r]) dp[j][r] = 1;
    25         }
    26     }
    27     for(int i = 1; i <= n; i ++) {
    28         for(int j = i; j <= n; j ++) {
    29             ans[getK(i,j)] ++;
    30         }
    31     }
    32     for(int i = n; i > 0; i --)
    33         ans[i-1] += ans[i];
    34     for(int i = 1; i <= n; i ++)
    35         printf("%d%c",ans[i],(i==n?'
    ':' '));
    36     return 0;
    37 }
  • 相关阅读:
    3dsmaxunity3d
    libav android移植交叉编译
    libav 由显卡中读取数据制作视频
    超详细mysql left join,right join,inner join用法分析
    VC常见入门问题总结
    c#皮肤美化
    论坛
    vc中文件的读写操作
    MySQL的mysqldump工具的基本用法
    perl产生随机数
  • 原文地址:https://www.cnblogs.com/xingkongyihao/p/7270686.html
Copyright © 2020-2023  润新知