zoukankan      html  css  js  c++  java
  • 【BZOJ】【2565】最长双回文串

    Manacher算法


      找出一个最长子串S=X+Y,且X和Y都是回文串,求最长的长度是多少……

      同时找两个串明显很难搞啊……但是我们可以先找到所有的回文串!在找回文串的同时我们可以预处理出来l[i]和r[i]分别表示从 i 这个位置开始向左/右最长的回文串有多长,那么我们枚举两个回文串的分割点更新答案即可。

     1 /**************************************************************
     2     Problem: 2565
     3     User: Tunix
     4     Language: C++
     5     Result: Accepted
     6     Time:80 ms
     7     Memory:4496 kb
     8 ****************************************************************/
     9  
    10 //BZOJ 2565
    11 #include<cstdio>
    12 #include<cstring>
    13 #include<cstdlib>
    14 #include<iostream>
    15 #include<algorithm>
    16 #define rep(i,n) for(int i=0;i<n;++i)
    17 #define F(i,j,n) for(int i=j;i<=n;++i)
    18 #define D(i,j,n) for(int i=j;i>=n;--i)
    19 using namespace std;
    20 typedef long long LL;
    21 inline int getint(){
    22     int r=1,v=0; char ch=getchar();
    23     for(;!isdigit(ch);ch=getchar()) if(ch=='-')r=-1;
    24     for(; isdigit(ch);ch=getchar()) v=v*10+ch-'0';
    25     return r*v;
    26 }
    27 const int N=1e5+10,INF=~0u>>2;
    28 /*******************template********************/
    29 char s[N];
    30 int p[N<<1],a[N<<1],l[N<<1],r[N<<1],n;
    31 int main(){
    32     scanf("%s",s);
    33     n=strlen(s);
    34     F(i,1,n) a[i<<1]=s[i-1];
    35     n=n<<1|1;
    36  
    37     int id=0,mx=0;
    38     F(i,1,n){
    39         if (mx>i) p[i]=min(p[2*id-i],mx-i);
    40         while(i-p[i]-1>0 && i+p[i]+1<=n && a[i-p[i]-1]==a[i+p[i]+1]){
    41             p[i]++;
    42             l[i+p[i]]=max(l[i+p[i]],p[i]);
    43             r[i-p[i]]=max(r[i-p[i]],p[i]);
    44         }
    45         if (p[i]+i>mx) mx=p[i]+i,id=i;
    46         l[i+p[i]]=max(l[i+p[i]],p[i]);
    47         r[i-p[i]]=max(r[i-p[i]],p[i]);
    48     }
    49     /*
    50     F(i,1,n) printf("%c ",a[i]!=0?a[i]:'#'); puts("");
    51     F(i,1,n) printf("%d ",p[i]); puts("");
    52     F(i,1,n) printf("%d ",l[i]); puts("");
    53     F(i,1,n) printf("%d ",r[i]); puts("");
    54     */
    55     int ans=0;
    56     F(i,1,n) if(l[i]+r[i]>ans) ans=l[i]+r[i];
    57     printf("%d
    ",ans);
    58     return 0;
    59 }
    View Code
  • 相关阅读:
    端午节
    使用MetaWeblog写博客
    Ajax 跨域操作
    MetaWeblogApi 开发, 离线写博客
    大三开学
    JVM003ConcurrentHashMap底层原理是什么
    JVM009JVM性能调优概述
    JVM006Java类加载器有哪些
    JVM004GC如何判断对象可以被回收
    JVM008JVM内存结构如何划分
  • 原文地址:https://www.cnblogs.com/Tunix/p/4397859.html
Copyright © 2011-2022 走看看