zoukankan      html  css  js  c++  java
  • hdu多校第二场1009 (hdu6599) I Love Palindrome String 回文自动机/字符串hash

    题意:

    找出这样的回文子串的个数:它本身是一个回文串,它的前一半也是一个回文串

    输出格式要求输出l个数字,分别代表长度为1~l的这样的回文串的个数

    题解:

    (回文自动机和回文树是一个东西)

    首先用回文自动机求出所有本质不同的字符串,以及它们出现的次数,把前半部分的字符串和后半部分的字符串分别hash一遍,看他们是不是相等。

    构造好回文自动机后,在回文自动机上dfs,向下传递当前字符串长度,正向,反向hash值,每次递归因为只增加了一个字母,所以可以O(1)计算。

    #include "bits/stdc++.h"
    using namespace std;
    const double eps = 1e-8;
    #define reg register
    #define lowbit(x) x&-x
    #define pll pair<ll,ll>
    #define pii pair<int,int>
    #define fi first
    #define se second
    #define makp make_pair
    int dcmp(double x) {
        if (fabs(x) < eps) return 0;
        return (x > 0) ? 1 : -1;
    }
    typedef long long ll;
    typedef unsigned long long ull;
    const ull hash1 = 201326611;
    const ull hash2 = 50331653;
    const int N = 300000 + 10;
    const int M = 1000 + 10;
    const int inf = 0x3f3f3f3f;
    const ll mod = 998244353;
    ll ret[N];
    ull ha[N], pp[N];
    ull getha(int l, int r) {
        if (l == 0) return ha[r];
        return ha[r] - ha[l - 1] * pp[r - l + 1];
    }
    bool check(int l, int r) {
        int len = r - l + 1;
        int mid = (l + r) >> 1;
        if (len & 1) return getha(l, mid) == getha(mid, r);
        else return getha(l, mid) == getha(mid + 1, r);
    }
    struct Palindromic_Tree {
        int nxt[N][30], fail[N], cnt[N];
        int num[N], len[N], s[N], id[N];
        int last, n, p;
        int newnode(int l) {
            memset(nxt[p], 0, sizeof(nxt[p]));
            cnt[p] = num[p] = 0;
            len[p] = l;
            return p++;
        }
        void init() {
            p = 0;
            newnode(0), newnode(-1);
            last = n = 0;
            s[0] = -1;
            fail[0] = 1;
        }
        int get_fail(int x) {
            while (s[n - len[x] - 1] != s[n]) x = fail[x];
            return x;
        }
        void add(int c) {
            c -= 'a';
            s[++n] = c;
            int cur = get_fail(last);
            if (!nxt[cur][c]) {
                int now = newnode(len[cur] + 2);
                fail[now] = nxt[get_fail(fail[cur])][c];
                nxt[cur][c] = now;
                num[now] = num[fail[now]] + 1;
            }
            last = nxt[cur][c];
            cnt[last]++, id[last] = n;
        }
        ll Count() {
            for (int i = p - 1; i >= 0; i--) cnt[fail[i]] += cnt[i];
            for (int i = 2; i < p; i++) {
                ///cout << id[i] - len[i] << " " << id[i] - 1 << endl;
                if (check(id[i] - len[i], id[i] - 1)) {
                    ret[len[i]] += cnt[i];
                }
            }
            return 0;
        }
    } pam;
    char str[N];
    int main() {
        pp[0] = 1;
        for (int i = 1; i < N; i++) {
            pp[i] = hash1 * pp[i - 1];
        }
        while (~scanf("%s", str)) {
            memset(ret, 0, sizeof(ret));
            pam.init();
            int len = strlen(str);
            ha[0] = str[0];
            for (int i = 0; i < len; i++) {
                pam.add(str[i]);
            }
            for (int i = 1; i < len; i++) {
                ha[i] = ha[i - 1] * hash1 + str[i];
            }
            pam.Count();
            printf("%lld", ret[1]);
            for (int i = 2; i <= len; i++) {
                printf(" %lld", ret[i]);
            }
            printf("
    ");
        }
        return 0;
    }
  • 相关阅读:
    ZOJ 1649: Rescue(BFS)
    UVA
    hdu2458:Kindergarten (最大独立集)
    hdu3829:Cat VS Dog (最大独立集)
    Java 泛型
    request.getParameter() 和request.getAttribute() 区别
    Solr版本安装部署指南
    java.sql.SQLException: Incorrect string value: 'xE6x88x91xE7x9Ax84...' for column 'groupName'
    Incorrect string value: 'xF0x9Fx98x84xF0x9F
    java里面byte数组和String字符串怎么转换
  • 原文地址:https://www.cnblogs.com/isakovsky/p/11259044.html
Copyright © 2011-2022 走看看