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.
The first line contains the string s (1 ≤ |s| ≤ 5000) consisting of lowercase English letters.
Print |s| integers — palindromic characteristics of string s.
abba
6 1 0 0
abacaba
12 4 1 0 0 0 0
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<iostream> #include<cstdio> #include<queue> #include<algorithm> #include<cstring> #include<string> using namespace std; typedef long long LL; #define MAXN 5050 #define N 100 /* 1阶回文串就是左右两边读相等 k 回文串就是从中间分开 左右两边都是k-1阶回文串 预处理a[i][j]确定i 到j 是不是回文串 然后递归 找每个固定阶的子串 k阶串肯定是k+1阶串! */ int g[MAXN][MAXN], ans[MAXN]; char str[MAXN]; int solve(int l, int r) { if (!g[l][r]) return 0;//不回文 if (l == r) return 1; if (l + 1 == r) return 2; if ((l - r + 1) % 2 == 0) return solve(l, (l + r) / 2) + 1; else return solve(l, (l + r) / 2 - 1) + 1; } int main() { scanf("%s", str + 1); int len = strlen(str+1); for (int i = 1; i <= len; i++) { g[i][i] = 1; if (i + 1 <= len&&str[i] == str[i + 1]) g[i][i + 1] = 1; } for (int k = 3; k <= len; k++) { for (int i = 1; i <= len; i++) { int r = i + k - 1; if (r > len) break; if (g[i + 1][r - 1] && str[r] == str[i]) g[i][r] = 1; } } for (int i = 1; i <= len; i++) { for (int j = 1; j <= len; j++) ans[solve(i, j)]++;//solve(i,j)b表示从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; }