【SPOJ1297】Palindrome (SA+RMQ)
求最长回文串。把原串翻转后,加在原串后面,中间插入一个辨别字符。然后求SA,Height。然后枚举每个字母作为回文串中心,分长度为奇数和偶数去讨论:奇数求 suffix(i)和suffix(n-i+1)的最长公共前缀,偶数则求suffix(i)和suffix(n-i+2)(当然,i=1时不成立) 。然后问题就是求最长公共前缀了,转换为RMQ问题,O(nlogn)预处理,O(1)询问即可.
1 const maxn=2419; 2 3 var 4 x,y,rank,sa,h,c:array[0..maxn] of longint; 5 s:ansistring; 6 f:array[0..maxn,0..15] of longint; 7 t,q,n:longint; 8 9 function max(x,y:longint):longint; begin if x>y then exit(x) else exit(y); end; 10 function min(x,y:longint):longint; begin if x<y then exit(x) else exit(y); end; 11 procedure swap(var x,y:longint);var tmp:longint; begin tmp:=x; x:=y;y:=tmp; end; 12 procedure make; 13 var i,j,p,tot:longint; 14 begin 15 p:=1; 16 while p<n do 17 begin 18 fillchar(c,sizeof(c),0); 19 for i:= 1 to n-p do y[i]:=rank[i+p]; 20 for i:= n-p+1 to n do y[i]:=0; 21 for i:= 1 to n do inc(c[y[i]]); 22 for i:= 1 to n do inc(c[i],c[i-1]); 23 for i:= 1 to n do 24 begin 25 sa[c[y[i]]]:=i; 26 dec(c[y[i]]); 27 end; 28 fillchar(c,sizeof(c),0); 29 for i:= 1 to n do x[i]:=rank[i]; 30 for i:= 1 to n do inc(c[x[i]]); 31 for i:= 1 to n do inc(c[i],c[i-1]); 32 for i:= n downto 1 do 33 begin 34 y[sa[i]]:=c[x[sa[i]]]; 35 dec(c[x[sa[i]]]); 36 end; 37 for i:= 1 to n do sa[y[i]]:=i; 38 tot:=1; 39 rank[sa[1]]:=1; 40 for i:= 2 to n do 41 begin 42 if (x[sa[i]]<>x[sa[i-1]]) or (x[sa[i]+p]<>x[sa[i-1]+p]) then inc(tot); 43 rank[sa[i]]:=tot; 44 end; 45 p:=p<<1; 46 end; 47 end; 48 49 procedure makeh; 50 var i,j,p:longint; 51 begin 52 h[1]:=0; p:=0; 53 for i:= 1 to n do 54 begin 55 p:=max(p-1,0); 56 if rank[i]=1 then continue; 57 j:=sa[rank[i]-1]; 58 while (i+p<=n) and (j+p<=n) and (s[i+p]=s[j+p]) do inc(p); 59 h[rank[i]]:=p; 60 end; 61 // for i:= 1 to n do write(h[i],' '); 62 // writeln; 63 end; 64 65 procedure rmq; 66 var i,j:longint; 67 begin 68 fillchar(f,sizeof(f),$7f); 69 for i:= 1 to n do f[i,0]:=h[i]; 70 for i:= 1 to trunc(ln(n)/ln(2)) do 71 for j:= 1 to n-1<<i+1 do 72 f[j,i]:=min(f[j,i-1],f[j+1<<(i-1),i-1]); 73 end; 74 75 function lcp(x,y:longint):longint; 76 var t:longint; 77 begin 78 x:=rank[x]; y:=rank[y]; 79 if x>y then swap(x,y); 80 if x<y then x:=x+1; 81 t:=trunc(ln(y-x+1)/ln(2)); 82 exit(min(f[x,t],f[y-1<<t+1,t])); 83 end; 84 85 procedure init; 86 var i,j,tot:longint; 87 ch:char; 88 begin 89 readln(s); 90 s:=s+'#'; 91 for i:= length(s)-1 downto 1 do s:=s+s[i]; 92 n:=length(s); 93 for i:= 1 to n do x[i]:=ord(s[i]); 94 fillchar(c,sizeof(c),0); 95 for i:= 1 to n do inc(c[x[i]]); 96 for i:= 1 to 180 do inc(c[i],c[i-1]); 97 for i:= 1 to n do 98 begin 99 sa[c[x[i]]]:=i; 100 dec(c[x[i]]); 101 end; 102 rank[sa[1]]:=1; 103 tot:=1; 104 for i:= 2 to n do 105 begin 106 if x[sa[i]]<>x[sa[i-1]] then inc(tot); 107 rank[sa[i]]:=tot; 108 end; 109 make; 110 makeh; 111 rmq; 112 end; 113 114 procedure solve; 115 var ans,st,i,k:longint; 116 begin 117 ans:=0;st:=0; 118 for i:= 1 to n do 119 begin 120 k:=lcp(i,n-i+1); 121 if k*2-1>ans then 122 begin 123 st:=i-k+1; 124 ans:=k*2-1; 125 end; 126 if i>1 then 127 begin 128 k:=lcp(i,n-i+2); 129 if k*2>ans then 130 begin 131 st:=i-k; 132 ans:=k*2; 133 end; 134 end; 135 end; 136 for i:= st to st+ans-1 do write(s[i]); 137 end; 138 139 Begin 140 init; 141 solve; 142 End.
View Code
转载于:https://www.cnblogs.com/EC-Ecstasy/p/4168191.html
【SPOJ1297】Palindrome (SA+RMQ)相关推荐
- 【BZOJ3489】A simple rmq problem kd-tree
[BZOJ3489]A simple rmq problem Description 因为是OJ上的题,就简单点好了.给出一个长度为n的序列,给出M个询问:在[l,r]之间找到一个在这个区间里只出现过 ...
- 【LeetCode】Palindrome Partitioning 解题报告
[题目] Given a string s, partition s such that every substring of the partition is a palindrome. Retur ...
- 【Leetcode】Palindrome Number
Determine whether an integer is a palindrome. Do this without extra space. 思路:若使用[Leetcode]Reverse I ...
- 【luogu1816】忠(RMQ问题、线段树)
题面 RMQ问题 题解 线段树 #include<iostream> #include<algorithm> using namespace std; const int ma ...
- 【9】Palindrome Number
Determine whether an integer is a palindrome. Do this without extra space. 首先负数不是回文数. 对于正数,求一下它倒过来的数 ...
- 【LeetCode】Palindrome Number(回文数)
这道题是LeetCode里的第9道题. 题目说的: 判断一个整数是否是回文数.回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数. 示例 1: 输入: 121 输出: true 示例 2: ...
- 【BZOJ3489】A simple rmq problem(树套树)
链接w:http://www.lydsy.com/JudgeOnline/problem.php?id=3489 题解:http://blog.csdn.net/PoPoQQQ/article/det ...
- 【Kubernetes】k8s的安全管理详细说明【SA配置、k8s安装dashboard、资源限制(resource、limit、resourcequota)】
文章目录 环境准备 token验证&&kubeconfig验证 role和clusterrole赋权 sa[Service Account] sa总结 1.service accoun ...
- 【LeetCode】字符串 string(共112题)
[3]Longest Substring Without Repeating Characters (2019年1月22日,复习) [5]Longest Palindromic Substring ( ...
最新文章
- 角色转移服务器维护怎么回事,服务器互通及游戏角色转移说明
- 过去50年最重要的统计学思想!
- 建一所希望小学需要600万!
- 【转】网络编程常见问题总结
- css3 固定,CSS3 calc()不适用于固定位置/绝对位置
- Java即时类| toString()方法与示例
- php删除数组中的空元素_PHP | 从数组中删除所有出现的元素
- 存储过程C语言与PL/pgSQL实现的效率对比
- ThinkPHP5如何引用新建的配置文件?
- 关于树的父子节点的图形化展示
- CCF NOI1053 相似度
- 使用Socket类接收和发送数据
- JS学习总结(13)——DOM
- 解读微信第三方平台-代小程序开发
- 数据压缩和归档(二)、zipfile
- 微服务实施笔记(四)——部署服务发现
- 笔记本电脑插过一次typeC的耳机之后在插3.5的圆孔耳机不能用?
- “科林明伦杯”哈尔滨理工大学第十届程序设计竞赛题解 H
- Norton AntiVirus (诺顿杀毒)v9.0 简体中文企业版http://down.hotlife.cn/html/download/2006/5/30/1148978165.shtml
- PyQt5——显示图片
热门文章
- 计算机安全的重要性 小论文,网络安全的重要性初中议论文
- c语言 结构体声明和引用、,结构体的声明与自引用
- matlab怎么利用圆形度提取园,基于Matlab+GUI图像处理的物料粒度与圆形度测试.pdf...
- 计算机组装与维护心得体会作文,《计算机维护与局域网建设》学习心得
- jmeter debug sample不在查看结果树中显示_Jmeter线程组间传递参数
- ubuntu 开机后不动_Ubuntu启动时停止的问题
- php empty判断0,PHP empty() 检测一个变量是否为空
- Vue使用v-for绑定两个属性拼接渲染界面
- Python制作彩色验证码
- 20200329:K 个一组翻转链表(leetcode25)