思路:

论文题……*n

倒过来接上 分奇偶讨论 求LCP 搞棵线段树即可

  1. //By SiriusRen
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <algorithm>
  5. using namespace std;
  6. #define N 5555
  7. int cases,pos,maxans,n,cntA[N],cntB[N],A[N],B[N],rk[N],sa[N],tsa[N],ht[N];
  8. char s[N];
  9. void SA(){
  10. memset(cntA,0,sizeof(cntA));
  11. for(int i=1;i<=n;i++)cntA[s[i]]++;
  12. for(int i=1;i<=256;i++)cntA[i]+=cntA[i-1];
  13. for(int i=n;i;i--)sa[cntA[s[i]]--]=i;
  14. rk[sa[1]]=1;
  15. for(int i=2;i<=n;i++)rk[sa[i]]=rk[sa[i-1]]+(s[sa[i]]!=s[sa[i-1]]);
  16. for(int l=1;rk[sa[n]]<n;l<<=1){
  17. memset(cntA,0,sizeof(cntA));
  18. memset(cntB,0,sizeof(cntB));
  19. for(int i=1;i<=n;i++)
  20. cntA[A[i]=rk[i]]++,
  21. cntB[B[i]=i+l<=n?rk[i+l]:0]++;
  22. for(int i=1;i<=n;i++)cntA[i]+=cntA[i-1],cntB[i]+=cntB[i-1];
  23. for(int i=n;i;i--)tsa[cntB[B[i]]--]=i;
  24. for(int i=n;i;i--)sa[cntA[A[tsa[i]]]--]=tsa[i];
  25. rk[sa[1]]=1;
  26. for(int i=2;i<=n;i++)rk[sa[i]]=rk[sa[i-1]]+(A[sa[i]]!=A[sa[i-1]]||B[sa[i]]!=B[sa[i-1]]);
  27. }
  28. for(int i=1,j=0;i<=n;i++){
  29. j=j?j-1:0;
  30. while(s[i+j]==s[sa[rk[i]-1]+j])j++;
  31. ht[rk[i]]=j;
  32. }
  33. }
  34. int tree[N*8];
  35. void build(int l,int r,int pos){
  36. if(l==r){tree[pos]=ht[l];return;}
  37. int mid=(l+r)>>1,lson=pos<<1,rson=pos<<1|1;
  38. build(l,mid,lson),build(mid+1,r,rson);
  39. tree[pos]=min(tree[lson],tree[rson]);
  40. }
  41. int query(int l,int r,int pos,int L,int R){
  42. if(l>=L&&r<=R)return tree[pos];
  43. int mid=(l+r)>>1,lson=pos<<1,rson=pos<<1|1;
  44. if(mid<L)return query(mid+1,r,rson,L,R);
  45. else if(mid>=R)return query(l,mid,lson,L,R);
  46. else return min(query(l,mid,lson,L,R),query(mid+1,r,rson,L,R));
  47. }
  48. int main(){
  49. scanf("%s",s+1),n=strlen(s+1);
  50. s[n+1]='#';
  51. for(int i=1;i<=n;i++)s[n+i+1]=s[n-i+1];
  52. n=n+n+1;
  53. SA(),build(1,n,1);
  54. for(int i=1;i<=n/2;i++){
  55. int tempx=min(rk[i],rk[n-i+1]),tempy=max(rk[i],rk[n-i+1]),jy;
  56. jy=query(1,n,1,tempx+1,tempy);
  57. if(maxans<jy*2-1)maxans=jy*2-1,pos=i-jy+1;
  58. else if(maxans==jy*2-1&&pos>i-jy+1)pos=i-jy+1;
  59. tempx=min(rk[i+1],rk[n-i+1]),tempy=max(rk[i+1],rk[n-i+1]);
  60. jy=query(1,n,1,tempx+1,tempy);
  61. if(maxans<jy*2)maxans=jy*2,pos=i-jy+1;
  62. else if(maxans==jy*2&&pos>i-jy+1)pos=i-jy+1;
  63. }
  64. for(int i=pos;i<maxans+pos;i++)printf("%c",s[i]);
  65. }

URAL 1297 后缀数组+线段树的更多相关文章

  1. BZOJ 1396: 识别子串( 后缀数组 + 线段树 )

    这道题各位大神好像都是用后缀自动机做的?.....蒟蒻就秀秀智商写一写后缀数组解法..... 求出Height数组后, 我们枚举每一位当做子串的开头. 如上图(x, y是height值), Heigh ...

  2. 【XSY1551】往事 广义后缀数组 线段树合并

    题目大意 给你一颗trie树,令\(s_i\)为点\(i\)到根的路径上的字符组成的字符串.求\(max_{u\neq v}(LCP(s_u,s_v)+LCS(s_u,s_v))\) \(LCP=\) ...

  3. Luogu4770 NOI2018你的名字(后缀数组+线段树)

    即求b串有多少个本质不同的非空子串,在a串的给定区间内未出现.即使已经8102年并且马上就9102年了,还是要高举SA伟大旗帜不动摇. 考虑离线,将所有询问串及一开始给的串加分隔符连起来,求出SA.对 ...

  4. BZOJ 2865 字符串识别 | 后缀数组 线段树

    集训讲字符串的时候我唯一想出正解的题-- 链接 BZOJ 2865 题面 给出一个长度为n (n <= 5e5) 的字符串,对于每一位,求包含该位的.最短的.在原串中只出现过一次的子串. 题解 ...

  5. bzoj 1396: 识别子串 && bzoj 2865: 字符串识别【后缀数组+线段树】

    根据height数组的定义,和当前后缀串i最长的相同串的长度就是max(height[i],height[i+1]),这个后缀贡献的最短不同串长度就是len=max(height[i],height[ ...

  6. Codeforces 1063F - String Journey(后缀数组+线段树+dp)

    Codeforces 题面传送门 & 洛谷题面传送门 神仙题,做了我整整 2.5h,写篇题解纪念下逝去的中午 后排膜拜 1 年前就独立切掉此题的 ymx,我在 2021 年的第 5270 个小 ...

  7. [CF1063F]String Journey[后缀数组+线段树]

    题意 在 \(S\) 中找出 \(t\) 个子串满足 \(t_{i+1}\) 是 \(t_{i}\) 的子串,要让 \(t\) 最大. \(|S| \leq 5\times 10^5\). 分析 定义 ...

  8. BZOJ 2865 字符串识别(后缀数组+线段树)

    很容易想到只考虑后缀长度必须为\(max(height[rk[i]],height[rk[i]+1])+1\)(即\([i,i+x-1]\)代表的串只出现过一次)然后我正着做一遍反着做一遍,再取一个\ ...

  9. [CF653F] Paper task - 后缀数组,线段树,vector

    [CF653F] Paper task Description 给定一个括号序列,统计合法的本质不同子串的个数. Solution 很容易想到,只要在传统统计本质不同子串的基础上修改一下即可. 考虑经 ...

随机推荐

  1. 【刷题笔记】LeetCode 606. Construct String from Binary Tree

    题意 给一棵二叉树,把它转化为字符串返回.转化字符串的要求如下: 1.  null 直接转化为  () ;(这个要求其实有点误导人~) 2. 子节点用 () 包裹起来:(这是我自己根据例子添加的要求) ...

  2. checkbox改写

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. 队列(FIFO)详解

    写在前面的话: 一枚自学Java和算法的工科妹子. 算法学习书目:算法(第四版) Robert Sedgewick 算法视频教程:Coursera  Algorithms Part1&2 本文 ...

  4. ROS-opencv-人脸识别-物体追踪-二维码识别

    前言:人脸识别是基于人的脸部特征信息进行身份识别的一种生物识别技术.用摄像机或摄像头采集含有人脸的图像或视频流,并自动在图像中检测和跟踪人脸,进而对检测到的人脸进行脸部识别的一系列相关技术,通常也叫做 ...

  5. HD-ACM算法专攻系列(15)——Quoit Design

    问题描述: 源码: 经典问题——最近邻问题,标准解法 #include"iostream" #include"algorithm" #include" ...

  6. Request.QueryString["id"] 、Request.Params["id"] 的强大

    <form> <input type="text" name="id" value="值"> </form&g ...

  7. 错误:java.lang.IllegalStateException: TimerTask is scheduled already

    Process: com.multak.cookaraclient, PID: 27384 java.lang.RuntimeException: Unable to resume activity ...

  8. java读取文件流和写入

    package jsoup;import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStre ...

  9. BZOJ3529: [Sdoi2014]数表 莫比乌斯反演_树状数组

    Code: #include <cstdio> #include <algorithm> #include <cstring> #define ll long lo ...

  10. Python数据分析3------数据预处理(2)----字符串处理