hdu6599 I Love Palindrome String

Posted hyfer

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu6599 I Love Palindrome String相关的知识,希望对你有一定的参考价值。

由样例可知,题目中求的回文串数量,其实是本质不同的回文串数量,这个可以直接用回文树来做。

考虑前半段是回文串这个限制,这个东西回文树不好做,可以再套一个马拉车,然后记录一下插入到回文树的节点中最后一个字符的位置,使用马拉车快速判断这一段的前半段是不是回文串

#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <vector>
#define fo(i, l, r) for (int i = l; i <= r; i++)
#define fd(i, l, r) for (int i = r; i >= l; i--)
#define mem(x) memset(x, 0, sizeof(x))
#define ll long long
using namespace std;
const int maxn = 300050;
ll read()

    ll x = 0, f = 1;
    char ch = getchar();
    while (!(ch >= 0 && ch <= 9))
    
        if (ch == -)
            f = -1;
        ch = getchar();
    ;
    while (ch >= 0 && ch <= 9)
    
        x = x * 10 + (ch - 0);
        ch = getchar();
    ;
    return x * f;


char Ma[maxn * 2];
int Mp[maxn * 2];
void Manacher(char s[], int len)

    int l = 0;
    Ma[l++] = $;
    Ma[l++] = #;
    for (int i = 0; i < len; i++)
    
        Ma[l++] = s[i];
        Ma[l++] = #;
    
    Ma[l] = 0;
    int mx = 0, id = 0;
    for (int i = 0; i < l; i++)
    
        Mp[i] = mx > i ? min(Mp[2 * id-i], mx-i) : 1;
        while (Ma[i + Mp[i]] == Ma[i-Mp[i]])
            Mp[i]++;
        if (i + Mp[i] > mx)
        
            mx = i + Mp[i];
            id = i;
        
    


const int N = 300010, S = 26;
int all, son[N][S], fail[N], cnt[N], len[N], text[N], pos[N], last, tot;
int newnode(int l)

    for (int i = 0; i < S; i++)
        son[tot][i] = 0;
    cnt[tot] = 0, len[tot] = l;
    return tot++;

void init()

    last = tot = all = 0;
    newnode(0), newnode(-1);
    text[0] = -1, fail[0] = 1;

int getfail(int x)

    while (text[all - len[x] - 1] != text[all])
        x = fail[x];
    return x;

void add(int w,int p)

    text[++all] = w;
    int x = getfail(last);
    if (!son[x][w])
    
        int y = newnode(len[x] + 2);
        fail[y] = son[getfail(fail[x])][w];
        son[x][w] = y;
        pos[y] = p;
    
    cnt[last = son[x][w]]++;

void count()

    for (int i = tot - 1; ~i; i--)
        cnt[fail[i]] += cnt[i];

char s[maxn];
int slen, s2[maxn];
ll ans[maxn];
int flag;
inline bool check(int l,int r)
    int len = r-l+1;
    if(len==1)return true;
    r = (l+r)>>1;
    len = r-l+1;
    if(len&1)
        int t = l + (len>>1);
        t *= 2;
        return Mp[t]-1 >= len;
    else
        int t = l + (len >> 1);
        t = t*2-1;
        return Mp[t]-1 >= len;
    

void dfs(int u, int d)

    fo(i, 0, 25)
    
        if (son[u][i])
        
            s2[d + 1] = i;
            dfs(son[u][i], d + 1);
        
    
    if (d)
    
        int lenu = d + d - flag;
        int rp = pos[u];
        int lp = pos[u]-lenu+1;
        if(check(lp,rp))ans[d + d - flag] += cnt[u];
    

int main()

    int tt = 0;
    int T;
    while (scanf("%s", s + 1) != EOF)
    
        init();
        memset(ans, 0, sizeof(ans));
        slen = strlen(s + 1);
        fo(i, 1, slen)
        
            add(s[i] - a,i);
        
        count();
        Manacher(s+1,slen);
        flag = 0;
        dfs(0, 0);
        flag = 1;
        dfs(1, 0);
        printf("%lld", ans[1]);
        fo(i, 2, slen)
        
            printf(" %lld", ans[i]);
        
        putchar(\n);
    
    return 0;

 

以上是关于hdu6599 I Love Palindrome String的主要内容,如果未能解决你的问题,请参考以下文章

HDU 4632 Palindrome subsequence (区间DP)

HDU 6230 Palindrome (manacher+树状数组)

HDU4362 Palindrome subsequence (区间DP)

HDU 4632 Palindrome subsequence(区间DP求回文子序列数)

hdu-4632 Palindrome subsequence (回文子序列计数)

HDU-3033 I love sneakers! (分组背包)