zoukankan      html  css  js  c++  java
  • hdu6230

    hdu6230

    题意

    给出一个字符串,问有多少个子串 (S[1..3n-2](n geq 2)) 满足 (S[i]=S[2n-i]=S[2n+i-2] (1leq i leq n))

    分析

    Manacher 算法预处理下以每个下标为中心的最长回文串的长度。
    我们要找的子串由两个奇数长度的回文串重叠部分组成,用一个向量数组存下以每个下标作为左端的奇数长度回文串的中心位置,我们可以维护一个树状数组去计算答案。

    code

    #include<bits/stdc++.h>
    using namespace std;
    const int MAXN = 5e5 + 10;
    char s[MAXN << 1], t[MAXN << 1];
    int n, m, num[MAXN << 1];
    void init() {
        n = strlen(s);
        t[0] = '$';
        for(int i = 1; i <= 2 * n; i += 2) {
            t[i] = '#';
            t[i + 1] = s[i / 2];
        }
        t[2 * n + 1] = '#';
        t[2 * n + 2] = '!';
        m = 2 * n + 1;
        int mx = 0, id = 0;
        memset(num, 0, sizeof num);
        for(int i = 1; i <= m; i++) {
            if(mx > i) num[i] = min(mx - i, num[2 * id - i]);
            else num[i] = 1;
            while(t[i - num[i]] == t[i + num[i]]) num[i]++;
            if(i + num[i] > mx) {
                mx = i + num[i];
                id = i;
            }
        }
    }
    int f[MAXN];
    void update(int x) {
        while(x < MAXN) {
            f[x]++;
            x += x & -x;
        }
    }
    int query(int x) {
        int res = 0;
        while(x) {
            res += f[x];
            x -= x & -x;
        }
        return res;
    }
    vector<int> G[MAXN];
    int main() {
        int T;
        scanf("%d", &T);
        while(T--) {
            scanf("%s", s);
            init();
            memset(f, 0, sizeof f);
            for(int i = 0; i < n; i++) G[i].clear();
            for(int i = 2; i <= m; i += 2) {
                int x = i / 2 - 1, r = (num[i] - 1) / 2;
                if(t[i] != '#') {
                    num[x] = r;
                    if(r) G[x - r].push_back(x);
                } else num[x] = 0;
            }
            long long ans = 0;
            for(int i = 0; i < n; i++) {
                for(int j = 0; j < G[i].size(); j++) update(G[i][j]);
                ans += query(min(n, i + num[i])) - query(i);
            }
            printf("%lld
    ", ans);
        }
        return 0;
    }
    
  • 相关阅读:
    mininet和ryu控制器的连接
    Linux服务器(Ubuntu14.04)添加远程连接VNC Server
    KVM的前世今生
    Ubuntu下搭建ryu环境
    Ubuntu下搭建Mininet环境
    手机蓝牙
    常见的js算法面试题收集,es6实现
    前端笔试题面试题记录(上)
    关于js中onclick字符串传参问题(html="")
    Angular $scope和$rootScope事件机制之$emit、$broadcast和$on
  • 原文地址:https://www.cnblogs.com/ftae/p/7828514.html
Copyright © 2011-2022 走看看