COJ975 WZJ的数据结构(负二十五)
试题描述
输入一个字符串S,回答Q次问题,给你l,r,输出子序列[l,r]的最长连续回文串长度。
输入
第一行为一个字符串S。
第二行为一个正整数Q。
接下来Q行每行为l,r。
输出
对于每个询问,输出答案。
输入示例
aababababaabababaaa
4
1 3
2 6
1 10
2 7
输出示例
2
5
9
5
其他说明
1<=|S|,Q<=100000
1<=l<=r<=|S|
由于求区间的最长回文串长度,这显然不是很容易的事情,我们考虑用分块来维护答案。
我们每SIZE个元素分成一块,询问时要得到大块之间的答案以及小部分贡献的答案。
前者我们可以预处理出来(马拉车或PAM),时间复杂度O(N^2/SIZE)。
后者我们可以用PAM,当回文串的一段在小段时,肯定是左端在左小段,右端在右小段。两者是对称的,我们开始考虑怎么求回文串右端在右小段的答案。
预处理每个位置在PAM上的节点,但这可能超过询问边界,所以我们要不停地沿失配边向上走,当节点的的长度<=限制长度时返回。
如果暴力的话虽然对于随机数据表现很好,但会被特殊数据卡。因此我们可以用倍增来做,那么这一部分的时间复杂度为O(Q*SIZE*logSIZE)。
总时间复杂度为O(N^2/SIZE+Q*SIZE*logSIZE),实测SIZE取[150,200]即可。
#include<cstdio>
#include<cctype>
#include<queue>
#include<cmath>
#include<stack>
#include<cstring>
#include<algorithm>
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define ren for(int i=first[x];i;i=next[i])
using namespace std;
inline int read() {
int x=,f=;char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=-;
for(;isdigit(c);c=getchar()) x=x*+c-'';
return x*f;
}
const int maxn=;
char ch[maxn];
int lpos[maxn],rpos[maxn],nowret;
struct PAM {
int last,cnt,to[maxn][],l[maxn],fa[maxn];
int first[maxn],next[maxn],To[maxn],anc[maxn][],e;
void init() {
memset(to,,sizeof(to));
memset(l,,sizeof(l));
memset(fa,,sizeof(fa));
memset(first,,sizeof(first));
cnt=fa[]=;l[]=-;last=e=;
}
void extend(int c,int n,int id) {
int p=last;
while(ch[n]!=ch[n-l[p]-]) p=fa[p];
if(!to[p][c]) {
int np=++cnt,k=fa[p];l[np]=l[p]+;
while(ch[n]!=ch[n-l[k]-]) k=fa[k];
fa[np]=to[k][c];to[p][c]=np;
}
nowret=max(nowret,l[last=to[p][c]]);
if(id>) lpos[id]=last;
else rpos[-id]=last;
}
stack<int> S;
void dfs(int x) {
S.push(x);
while(!S.empty()) {
x=S.top();S.pop();
anc[x][]=fa[x];
rep(i,,) anc[x][i]=anc[anc[x][i-]][i-];
ren S.push(To[i]);
}
}
void AddEdge(int u,int v) {
To[++e]=v;next[e]=first[u];first[u]=e;
}
void build() {
fa[]=;rep(i,,cnt) if(i!=) AddEdge(fa[i],i);
dfs();
}
int solve(int x,int limit) {
if(l[x]<=limit) return l[x];
for(int i=;i>=;i--) if(l[anc[x][i]]>limit) x=anc[x][i];
return l[fa[x]];
}
}sol1,sol2;
int n,SIZE;
int ans[][],bl[maxn],st[maxn],en[maxn];
int main() {
scanf("%s",ch+);n=strlen(ch+);SIZE=;
rep(i,,n) {
bl[i]=(i-)/SIZE+;
en[bl[i]]=i;
if(!st[bl[i]]) st[bl[i]]=i;
}
rep(i,,bl[n]) {
sol1.init();nowret=;
char c=ch[st[i]-];ch[st[i]-]='~';
rep(j,st[i],n) {
sol1.extend(ch[j]-'a',j,);
ans[i][bl[j]]=max(ans[i][bl[j]],nowret);
}
ch[st[i]-]=c;
}
sol1.init();sol2.init();
rep(i,,n) sol1.extend(ch[i]-'a',i,i);
reverse(ch+,ch+n+);
rep(i,,n) sol2.extend(ch[i]-'a',i,-(n-i+));
sol1.build();sol2.build();
int m=read();
while(m--) {
int l=read(),r=read(),ret=;
if(bl[l]+>=bl[r]) rep(i,l,r) ret=max(ret,sol1.solve(lpos[i],i-l+));
else {
ret=ans[bl[l]+][bl[r]-];
rep(i,l,en[bl[l]]) ret=max(ret,sol2.solve(rpos[i],r-i+));
rep(i,st[bl[r]],r) ret=max(ret,sol1.solve(lpos[i],i-l+));
}
printf("%d\n",ret);
}
return ;
}
COJ975 WZJ的数据结构(负二十五)的更多相关文章
- 策略模式 Strategy 政策Policy 行为型 设计模式(二十五)
策略模式 Strategy 与策略相关的常见词汇有:营销策略.折扣策略.教学策略.记忆策略.学习策略.... “策略”意味着分情况讨论,而不是一概而论 面对不同年龄段的人,面对不同的商品,必然将会 ...
- Bootstrap <基础二十五>警告(Alerts)
警告(Alerts)以及 Bootstrap 所提供的用于警告的 class.警告(Alerts)向用户提供了一种定义消息样式的方式.它们为典型的用户操作提供了上下文信息反馈. 您可以为警告框添加一个 ...
- VMware vSphere 服务器虚拟化之二十五 桌面虚拟化之终端服务池
VMware vSphere 服务器虚拟化之二十五 桌面虚拟化之终端服务池 终端服务池是指由一台或多台微软终端服务器提供服务的桌面源组成的池.终端服务器桌面源可交付多个桌面.它具有以下特征: 1.终端 ...
- WCF技术剖析之二十五: 元数据(Metadata)架构体系全景展现[元数据描述篇]
原文:WCF技术剖析之二十五: 元数据(Metadata)架构体系全景展现[元数据描述篇] 在[WS标准篇]中我花了很大的篇幅介绍了WS-MEX以及与它相关的WS规范:WS-Policy.WS-Tra ...
- Bootstrap入门(二十五)JS插件2:过渡效果
Bootstrap入门(二十五)JS插件2:过渡效果 对于简单的过渡效果,只需将 transition.js 和其它 JS 文件一起引入即可.如果你使用的是编译(或压缩)版的bootstrap.js ...
- JAVA基础再回首(二十五)——Lock锁的使用、死锁问题、多线程生产者和消费者、线程池、匿名内部类使用多线程、定时器、面试题
JAVA基础再回首(二十五)--Lock锁的使用.死锁问题.多线程生产者和消费者.线程池.匿名内部类使用多线程.定时器.面试题 版权声明:转载必须注明本文转自程序猿杜鹏程的博客:http://blog ...
- JAVA之旅(二十五)——文件复制,字符流的缓冲区,BufferedWriter,BufferedReader,通过缓冲区复制文件,readLine工作原理,自定义readLine
JAVA之旅(二十五)--文件复制,字符流的缓冲区,BufferedWriter,BufferedReader,通过缓冲区复制文件,readLine工作原理,自定义readLine 我们继续IO上个篇 ...
- Java进阶(二十五)Java连接mysql数据库(底层实现)
Java进阶(二十五)Java连接mysql数据库(底层实现) 前言 很长时间没有系统的使用java做项目了.现在需要使用java完成一个实验,其中涉及到java连接数据库.让自己来写,记忆中已无从搜 ...
- 二十五. Python基础(25)--模块和包
二十五. Python基础(25)--模块和包 ● 知识框架 ● 模块的属性__name__ # my_module.py def fun1(): print("Hello& ...
随机推荐
- The Perfect Stall (incomplete)
恩,一看就知道是一道二分图最大匹配的题. 感动得发现自己不会做..果然我是太弱了.学校里真是麻烦死,根本没有时间好吗. (NOIP)会不会感动地滚粗啊? 然后稍微看看,恩,匈牙利算法. 真是感动得落泪 ...
- jQuery mobile 开发问题记录
一.动态加载页面问题 1.存在这样一个页面布局: main.html 为主界面A,B为该页面中的三个page,其中A为splitview左部分页面,B为右半部页面 a1.html 为一个独立的页面 a ...
- VMware Snapshot 工作原理
VMware中的快照是对VMDK在某个时间点的“拷贝”,这个“拷贝”并不是对VMDK文件的复制,而是保持磁盘文件和系统内存在该时间点的状态,以便在出现故障后虚拟机能够恢复到该时间点.如果对某个虚拟机创 ...
- 获取Ad用户信息
private]; } dt.Rows.Add(dr); } return dt; ...
- 2013 ACM/ICPC 长春网络赛F题
题意:两个人轮流说数字,第一个人可以说区间[1~k]中的一个,之后每次每人都可以说一个比前一个人所说数字大一点的数字,相邻两次数字只差在区间[1~k].谁先>=N,谁输.问最后是第一个人赢还是第 ...
- ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib
今天在linux里安装mysql,运行时遇到这样的错误 ERROR 2002 (HY000): Can't connect to local MySQL server through socket ' ...
- Java异常与异常处理简单使用
异常就是程序运行过程中阻止当前方法或作用域继续执行的问题: 任何程序都不能保证完全正常运行,当发生异常时,需要我们去处理异常,特别是一些比较重要的场景,异常处理的逻辑也会比较复杂,比如:给用户提示.保 ...
- BestCoder17 1001.Chessboard(hdu 5100) 解题报告
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5100 题目意思:有一个 n * n 的棋盘,需要用 k * 1 的瓷砖去覆盖,问最大覆盖面积是多少. ...
- 【python】choice函数
来源:http://www.runoob.com/python/func-number-choice.html 描述 choice() 方法返回一个列表,元组或字符串的随机项. 语法 以下是 choi ...
- opencv学习笔记(六)直方图比较图片相似度
opencv学习笔记(六)直方图比较图片相似度 opencv提供了API来比较图片的相似程度,使我们很简单的就能对2个图片进行比较,这就是直方图的比较,直方图英文是histogram, 原理就是就是将 ...