zoukankan      html  css  js  c++  java
  • bzoj3676

    后缀自动机+manacher

    听说本质不同的回文串只有O(n)个

    那么用manacher求出所有回文串,然后在sam上查找出现了几次就行了

    sam的性质又忘了。。。

    manacher也忘了。。。

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 3e5 + 5;
    int n, len, pos, mx;
    long long ans;
    int c[N << 1], a[N << 1], p[N << 1], fa[N << 1][21], f[N << 1], Pos[N];
    char s[N], S[N << 1];
    namespace SAM 
    {
        struct node {
            int val, par;
            int ch[26];
        } t[N << 1];
        int sz = 1, root = 1, last = 1;
        int nw(int _)
        {
            t[++sz].val = _;
            return sz;
        }
        void extend(int c)
        {
            int p = last, np = nw(t[p].val + 1);
            while(p && !t[p].ch[c]) t[p].ch[c] = np, p = t[p].par;
            if(!p) t[np].par = root;
            else
            {
                int q = t[p].ch[c];
                if(t[q].val == t[p].val + 1) t[np].par = q;
                else
                {
                    int nq = nw(t[p].val + 1);
                    memcpy(t[nq].ch, t[q].ch, sizeof(t[q].ch));
                    t[nq].par = t[q].par;
                    t[q].par = t[np].par = nq;
                    while(p && t[p].ch[c] == q) t[p].ch[c] = nq, p = t[p].par;
                }
            }
            last = np;
            Pos[t[np].val] = np;
            f[np] = 1;
        } 
        int query(int l, int r) 
        {
            int len = r - l + 1, now = Pos[r];
            for(int i = 20; i >= 0; --i) if(t[fa[now][i]].val >= len) now = fa[now][i];
            return f[now];
        }
    } using namespace SAM;
    int main()
    {
        scanf("%s", s + 1);
        n = strlen(s + 1);
        for(int i = 1; i <= n; ++i) extend(s[i] - 'a');
        for(int i = 1; i <= sz; ++i) ++c[t[i].val];
        for(int i = 1; i <= sz; ++i) c[i] += c[i - 1];
        for(int i = 1; i <= sz; ++i) a[c[t[i].val]--] = i;
        for(int i = sz; i; --i) f[t[a[i]].par] += f[a[i]];
        for(int i = 1; i <= sz; ++i) fa[i][0] = t[i].par;
        for(int j = 1; j <= 20; ++j)
            for(int i = 1; i <= sz; ++i)
                fa[i][j] = fa[fa[i][j - 1]][j - 1]; 
         
        S[0] = '-';
        for(int i = 1; i <= n; ++i) 
        {
            S[++len] = '#';
            S[++len] = s[i];
     
        }
        S[++len] = '#';
        S[++len] = '+';
        for(int i = 1; i <= len; ++i) 
        {
            if(i < mx) p[i] = min(mx - i, p[2 * pos - i]);
            while(S[i - p[i]] == S[i + p[i]]) 
            {
                ans = max(ans, 1LL * p[i] * query((i - p[i] + 1) >> 1, (i + p[i]) >> 1));
                ++p[i];
            }
            if(i + p[i] > mx)
            {
                pos = i;
                mx = i + p[i];
            }
        }
        printf("%lld
    ", ans);
        return 0;
    }
    View Code
  • 相关阅读:
    基于FPGA的ARP协议实现
    Modelsim 仿真错误集锦
    基于FPGA的IIC驱动设计
    状态机跑飞的解决办法
    基于FPGA的检测时钟脉冲的高电平及低电平的中点标志位设计
    基于FPGA的UART实现
    基于FPGA的数字秒表设计
    Matlab的常用调试方法
    基于FPGA的花样流水灯
    **time_limited.sof文件
  • 原文地址:https://www.cnblogs.com/19992147orz/p/8036413.html
Copyright © 2011-2022 走看看