• 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;
    }
    
  • 相关阅读:
    终于开通了
    <input>表单元素readonly时光标仍然可见
    关于字体
    SSI架构中get***方法潜在调用
    为uploads文件夹瘦身
    在JSP里使用CKEditor和CKFinder
    centos5.5上搭建svn服务器
    多文件上传
    属性化ATL,DCOM,SIM,IID
    BSTR转换成char*
  • 原文地址:https://www.cnblogs.com/ftae/p/7828514.html
Copyright © 2020-2023  润新知