网络流就先告一段落了

在进行其他训练之前,我决定先练一道后缀数组(对这个我还是比较有自信的)

虽然之前没用后缀数组解决过回文问题,但是稍微想想就知道,

要解决最长双倍回文,首先要解决最长回文序列,

要解决最长回文序列,首先要倒序添加原串然后LCP

任意两个后缀的LCP我就不多说了,

然后我们就可以求出以任意一个字符为中心展开的最长回文串(要小心,偶数长度的最长回文串)

然后就能求出每个字符向左向右延伸回文串能延伸多远,

最后在遍历一边就可以了。

 var h,sa,rank,x,y,sum:array[..] of longint;
    f:array[..,..] of longint;
    d:array[..] of longint;
    left,right:array[..] of longint;
    p,i,j,l,n,m,ans,t:longint;
    s:ansistring; function min(a,b:longint):longint;
  begin
    if a>b then exit(b) else exit(a);
  end; function max(a,b:longint):longint;
  begin
    if a>b then exit(a) else exit(b);
  end; procedure swap(var a,b:longint);
  var c:longint;
  begin
    c:=a;
    a:=b;
    b:=c;
  end; procedure suffix;
  var m,p,i,j:longint;
  begin
    for i:= to n do
    begin
      y[i]:=ord(s[i]);
      inc(sum[y[i]]);
    end;
    m:=;
    for i:= to m do
      inc(sum[i],sum[i-]);
    for i:=n downto do
    begin
      sa[sum[y[i]]]:=i;
      dec(sum[y[i]]);
    end;
    p:=;
    rank[sa[]]:=;
    for i:= to n do
    begin
      if y[sa[i]]<>y[sa[i-]] then inc(p);
      rank[sa[i]]:=p;
    end;
    m:=p;
    j:=;
    while m<n do
    begin
      y:=rank;
      fillchar(sum,sizeof(sum),);
      p:=;
      for i:=n-j+ to n do
      begin
        inc(p);
        x[p]:=i;
      end;
      for i:= to n do
        if sa[i]>j then
        begin
          inc(p);
          x[p]:=sa[i]-j;
        end;
      for i:= to n do
      begin
        rank[i]:=y[x[i]];
        inc(sum[rank[i]]);
      end;
      for i:= to m do
        inc(sum[i],sum[i-]);
      for i:=n downto do
      begin
        sa[sum[rank[i]]]:=x[i];
        dec(sum[rank[i]]);
      end;
      p:=;
      rank[sa[]]:=;
      for i:= to n do
      begin
        if (y[sa[i]]<>y[sa[i-]]) or (y[sa[i]+j]<>y[sa[i-]+j]) then inc(p);
        rank[sa[i]]:=p;
      end;
      m:=p;
      j:=j shl ;
    end;
    h[]:=;
    p:=;
    for i:= to n do
    begin
      if rank[i]= then continue;
      j:=sa[rank[i]-];
      while s[i+p]=s[j+p] do inc(p);
      h[rank[i]]:=p;
      if p> then dec(p);
    end;
  end; procedure rmq;
  begin
    t:=trunc(ln(n)/ln());
    d[]:=;
    for i:= to t do
      d[i]:=d[i-]*;     for i:= to n do
      f[i,]:=h[i];
    for j:= to t do
      for i:= to n do
        if (i+d[j]-<=n) then
          f[i,j]:=min(f[i,j-],f[i+d[j-],j-]);
  end; function ask(x,y:longint):longint;
  var k:longint;
  begin
    if x>y then swap(x,y);
    inc(x);
    k:=trunc(ln(y-x+)/ln());
    ask:=min(f[x,k],f[y-d[k]+,k]);
  end; begin
  readln(s);
  l:=length(s);
  s:=s+'*';
  for i:=l downto do
  begin
    s:=s+s[i];
    left[i]:=;
    right[i]:=;
  end;
  n:=length(s);
  suffix;
  rmq;
  for i:= to l do
  begin
    p:=ask(rank[i],rank[n+-i]);  //先求奇数长度的回文序列
    left[i-p+]:=max(left[i-p+],p*-);
    right[i+p-]:=max(right[i+p-],p*-);
    if i<>l then
    begin
      p:=ask(rank[i],rank[n-i]);  //偶数长度的回文序列
      if p> then dec(p);    //细节
      if p<> then
      begin
        left[i-p+]:=max(left[i-p+],*p);
        right[i+p]:=max(right[i+p],*p);
      end;
    end;
  end;
  for i:=l- downto do  //处理每个字符为回文串的一端的最远延伸
    right[i]:=max(right[i],right[i+]-);
  for i:= to l do
    left[i]:=max(left[i],left[i-]-);
  for i:= to l- do  //不难理解
    ans:=max(ans,right[i]+left[i+]);
  writeln(ans);
end.

bzoj2565的更多相关文章

  1. 【BZOJ2565】最长双回文串(回文树)

    [BZOJ2565]最长双回文串(回文树) 题面 BZOJ 题解 枚举断点\(i\) 显然的,我们要求的就是以\(i\)结尾的最长回文后缀的长度 再加上以\(i+1\)开头的最长回文前缀的长度 至于最 ...

  2. 【BZOJ2565】最长双回文串 Manacher

    [BZOJ2565]最长双回文串 Description 顺序和逆序读起来完全一样的串叫做回文串.比如acbca是回文串,而abc不是(abc的顺序为“abc”,逆序为“cba”,不相同).输入长度为 ...

  3. BZOJ2565 最长双回文串 【Manacher】

    BZOJ2565 最长双回文串 Description 顺序和逆序读起来完全一样的串叫做回文串.比如acbca是回文串,而abc不是(abc的顺序为"abc",逆序为"c ...

  4. 【BZOJ2565】最长双回文串 (Manacher算法)

    题目: BZOJ2565 分析: 首先看到回文串,肯定能想到Manacher算法.下文中字符串\(s\)是输入的字符串\(str\)在Manacher算法中添加了字符'#'后的字符串 (构造方式如下) ...

  5. 回文自动机(BZOJ2565)

    #include <cstdio> #include <cstring> #include <iostream> using namespace std; ][], ...

  6. bzoj2565: 最长双回文串

    manacher之后乱搞 #include <iostream> #include <cstdio> #include <cstring> #include < ...

  7. BZOJ2565: 最长双回文串(回文树)

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2565 记录一下每个点往前最长延伸位置,正反两遍,枚举分割点. #include<cstr ...

  8. BZOJ2565最长双回文串——manacher

    题目描述 顺序和逆序读起来完全一样的串叫做回文串.比如acbca是回文串,而abc不是(abc的顺序为“abc”,逆序为“cba”,不相同).输入长度为n的串S,求S的最长双回文子串T,即可将T分为两 ...

  9. 2019.03.02 bzoj2565: 最长双回文串(pam)

    传送门 题意简述:问最长的由两个回文串连接而成最长字串长度. 思路: 正反串各建一个pampampam然后就完了. 代码: #include<bits/stdc++.h> #define ...

随机推荐

  1. HDU 4763 (KMP算法)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4763 题目大意:给定一串字符,从中找出符合“EAEBE”格式的E的最大字符数.AB可以是任意数量的任意 ...

  2. poj 3565 uva 1411 Ants KM算法求最小权

    由于涉及到实数,一定,一定不能直接等于,一定,一定加一个误差<0.00001,坑死了…… 有两种事物,不难想到用二分图.这里涉及到一个有趣的问题,这个二分图的完美匹配的最小权值和就是答案.为啥呢 ...

  3. Linux中的简单命令

    history:打印你输过的命令      1.用户在shell中输入的命令会自动保存到内存缓冲区      2.在退出shell的时候,内存中的数据会刷新到磁盘文件:~/.bash_history ...

  4. C++ Vector

    在c++中,vector是一个十分有用的容器,下面对这个容器做一下总结. 1 基本操作 (1)头文件#include<vector>. (2)创建vector对象,vector<in ...

  5. SQL注入原理二

    随着B/S模式应用开发的发展,使用这种模式编写应用程序的程序员也越来越多. 但是由于程序员的水平及经验也参差不齐,相当大一部分程序员在编写代码的时候 ,没有对用户输入数据的合法性进行判断,使应用程序存 ...

  6. gwt 创建 超链接cell (HyperTextCell)

    package com.cnblogs.hooligen.client; import com.google.gwt.cell.client.AbstractCell; import com.goog ...

  7. Django环境搭建和项目创建

    1.下载安装python 2.打开shell(windows下cmd),安装虚拟环境工具:  "pip install virtualenv".(可以通过“python -m pi ...

  8. CoreBluetooth - TouchID应用

    支持系统和机型: iOS系统的指纹识别功能最低支持的机型为iPhone 5s,最低支持系统为iOS 8, 虽然安装iOS 7系统的5s机型可以使用系统提供的指纹解锁功能,但由于API并未开放,所以理论 ...

  9. UIMenuController搭配UIPasteboard,执行拷贝-黏贴操作-b

    一.基本概念 UIKit框架中,可以直接执行拷贝黏贴操作的有:UITextView.UITextField和UIWebView,其他控件需要实现相关方法. 关于UIPasteboard ·黏贴板是ap ...

  10. [Linux发行版] 常见Linux系统下载

    本专题页汇总最受欢迎的Linux发行版基本介绍和下载地址,如果您是一位刚接触Linux的新手,这里的介绍可能对您有所帮助,如果您是以为Linux使用前辈,也可以在评论处留下您宝贵意见和经验,以便让更多 ...