• 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('
    ');
        }
        return 0;
    }
  • 相关阅读:
    unittest单元测试框架之unittest工作原理(一)
    unittest单元测试框架之unittest案例(二)
    mysql 查询导出(txt,csv,xls)
    JS 无限长form表单提交
    PHP设计模式的六大设计原则
    MySql 双主多从配置指导
    MySQL5.7开多实例指导
    MySQL主从复制配置指导及PHP读写分离源码分析
    《单元测试之道Java版》的读书笔记
    《重构》的读书笔记–方法列表
  • 原文地址:https://www.cnblogs.com/hyfer/p/11575134.html
Copyright © 2020-2023  润新知