• BZOJ2565 最长双回文串 manacher


    终于找到水题了感动。。

    manacher模板都会吧。不会请点击左侧友链,找到FYJ大佬的博客,可以看他博客,或通过教他泡妹子等正常方式让他给你讲manacher。

    首先,我们在进行manager的过程中,可以求出每个位置为中心的最长回文子串长度

    那么,我们可以枚举断点,把以该点结尾的前面最长回文子串长度与从该点开头的最长回文子串长度加起来,取max,就能找到我们想要的答案了。

    每找到一个中心及它的半径,都扫一遍它的覆盖区间,进行统计?

    于是我们就找到了一个n²的优秀做法了[/手动滑稽]

    继续思考,以某个点为起点的最长长度,必定是从它的前面节点转移来的(我们在马拉车找回文串时将长度存在了这个回文串开始的地方),那么方程为start[i]=max(start[i],start[i-2]-2)  (-2是为了忽略插入的'#'号) ,以某个点为终点的长度同理,反向O(n)扫一遍就行了,最后再扫一遍统计答案,诶,好像就可以A了耶

    #include<bits/stdc++.h>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<queue>
    #include<deque>
    #include<list>
    #include<set>
    #include<vector>
    #include<iostream>
    #define ll long long
    #define re register
    #define inf 0x3f3f3f3f
    #define inl inline
    #define sqr(x) (x*x)
    //#define eps 1e-8
    #define debug printf("debug
    ");
    //#pragma comment(linker, "/STACK:1024000000,1024000000")
    //#pragma GCC optimize (2)
    //#pragma G++ optimize (2)
    using namespace std;
    //const ll mod;
    const ll MAXN=1e5+10;
    inl ll read() {
        re ll x = 0; re int f = 1;
        char ch = getchar();
        while(ch<'0'||ch>'9') { if(ch== '-' ) f = -1; ch = getchar(); }
        while(ch>='0'&&ch<='9') {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
        return x * f;
    }
    inl char readc() {
        char ch=getchar();
        while(('z'<ch||ch<'a')&&('Z'<ch||ch<'A')) ch=getchar();
        return ch;
    }
    inl void write(re ll x){
        if(x>=10)write(x/10);
        putchar(x%10+'0');
    }
    inl void writeln(re ll x){
        if(x<0) {x=-x;putchar('-');}
        write(x); puts("");
    }
    inl ll gcd(re ll x,re ll y){while(y^=x^=y^=x%=y);return x;}
    inl void FR() {
        freopen(".in","r",stdin);
        freopen(".out","w",stdout);
    }
    inl void FC() {
        fclose(stdin);
        fclose(stdout);
    }
    char s[MAXN],ss[MAXN<<2];
    ll n,nn,st[MAXN<<2],ed[MAXN<<2],hw[MAXN<<2];
    void manacher() {
        ll mr=0,mid=0;
        for(re ll i=1;i<=nn;i++) {
            if(i<mr) hw[i]=min(hw[(mid<<1)-i],hw[mid]+mid-i);
            else hw[i]=1;
            while(ss[i+hw[i]]==ss[i-hw[i]]) hw[i]++;
            if(i+hw[i]>mr) {mr=i+hw[i];mid=i;}
        }
    }
    int main() {
    //  FR(); 
        scanf("%s",s+1);n=strlen(s+1);
        ss[0]=ss[1]='#';nn=n<<1|1;
        for(re ll i=1;i<=n;i++) {
            ss[i<<1]=s[i];ss[i<<1|1]='#';
        }
        manacher();
        for(re ll i=1;i<=nn;i++) {
            ed[i+hw[i]-1]=max(ed[i+hw[i]-1],hw[i]-1); 
            st[i-hw[i]+1]=max(st[i-hw[i]+1],hw[i]-1); 
        }
        for(re ll i=1;i<=nn;i+=2) st[i]=max(st[i],st[i-2]-2);
        for(re ll i=nn;i>=1;i-=2) ed[i]=max(ed[i],ed[i+2]-2);
        re ll ans=0;
        for(re ll i=1;i<=nn;i+=2) {
            if(st[i]&&ed[i]) {ans=max(ans,st[i]+ed[i]);}
        }
        writeln(ans);
    //  FC();
        return 0;
    }
  • 相关阅读:
    java位运算
    AmCharts realtime flush example //add by liuwei 20120929
    配置Linux—LVS (DR)
    LVS(Linux Virtual Server) 学习笔记
    一个由sizeof引出的有意思的问题
    关于IsDebuggerPresent
    我的第一个python程序
    听Robert C. Richardson的报告会很失望
    杯具了,为啥不去tencent的实习生招聘呢
    通过信号量机制解决生产者消费者问题的模拟程序
  • 原文地址:https://www.cnblogs.com/20020723YJX/p/9385333.html
Copyright © 2020-2023  润新知