UVA - 12338 Anti-Rhyme Pairs(后缀数组)
题目链接:点击查看
题目大意:给出n个字符串和m个查询,每次查询给出两个字符串的下标,询问这两个字符串的最长公共前缀的长度
题目分析:因为需要询问最长公共前缀,而且查询的m给到了1e6,这也要求我们每次查询必须在O(1)或O(logn)的时间复杂度内完成,所以我们可以选择后缀数组,将n个字符串拼接到一起后,跑出height数组后,用RMQ预处理一下,就可以O(1)获得两个字符串的最长公共前缀了
记得注意一下数组的大小,因为我们需要添加至多N个特殊字符,以及原字符串总长度有1e6,所以后缀数组的长度应该是1e6+1e5,然后st表的话第二维应该开至少21,因为2的20次方是小于1e6+1e5的
代码:
#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cstring>
#include<algorithm>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<cmath>
#include<sstream>
using namespace std;typedef long long LL;const int inf=0x3f3f3f3f;const int N=2e6+100;char str[N];int sa[N]; //SA数组,表示将S的n个后缀从小到大排序后把排好序的
//的后缀的开头位置顺次放入SA中
int t1[N],t2[N],c[N];int rk[N],height[N],id[N],str_len[N],len;int s[N];int st[N][25];void build_sa(int s[],int n,int m)//n为添加0后的总长
{int i,j,p,*x=t1,*y=t2;for(i=0;i<m;i++) c[i]=0;for(i=0;i<n;i++) c[x[i]=s[i]]++;for(i=1;i<m;i++) c[i]+=c[i-1];for(i=n-1;i>=0;i--) sa[--c[x[i]]]=i;for(j=1;j<=n;j<<=1) {p=0;for(i=n-j;i<n;i++) y[p++]=i;for(i=0;i<n;i++) if(sa[i]>=j) y[p++]=sa[i]-j;for(i=0;i<m;i++) c[i]=0;for(i=0;i<n;i++) c[x[y[i]]]++;for(i=1;i<m;i++) c[i]+=c[i-1];for(i=n-1;i>=0;i--) sa[--c[x[y[i]]]]=y[i];swap(x,y);p=1,x[sa[0]]=0;for(i=1;i<n;i++) x[sa[i]]=y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+j]==y[sa[i]+j]?p-1:p++;if(p>=n) break;m=p;}
}void get_height(int s[],int n)//n为添加0后的总长
{int i,j,k=0;for(i=0;i<=n;i++)rk[sa[i]]=i;for(i=0;i<n;i++) {if(k) k--;j=sa[rk[i]-1];while(s[i+k]==s[j+k]) k++;height[rk[i]]=k;}
}void solve(int base=128)
{build_sa(s,len+1,base);get_height(s,len);
}void ST_build()
{for(int i=1;i<=len;i++)st[i][0]=height[i];for(int i=1;i<=log2(len);i++)for(int j=1;j+(1<<i)-1<=len;j++)st[j][i]=min(st[j][i-1],st[j+(1<<i-1)][i-1]);
}int ST_query(int a,int b)
{int l=rk[a],r=rk[b];if(l>r)swap(l,r);l++;int k=log2(r-l+1);return min(st[l][k],st[r-(1<<k)+1][k]);
}int main()
{
// freopen("input.txt","r",stdin);
// ios::sync_with_stdio(false);int w;cin>>w;int kase=0;while(w--){int n;scanf("%d",&n);int pos=30;len=0;for(int i=1;i<=n;i++){scanf("%s",str);id[i]=len;str_len[i]=strlen(str);for(int j=0;str[j];j++)s[len++]=str[j]-'a'+1;s[len++]=pos++;}s[len]=0;solve(pos);ST_build();int m;scanf("%d",&m);printf("Case %d:\n",++kase);while(m--){int l,r;scanf("%d%d",&l,&r);if(l==r)printf("%d\n",str_len[l]);elseprintf("%d\n",ST_query(id[l],id[r]));}}return 0;
}
UVA - 12338 Anti-Rhyme Pairs(后缀数组)相关推荐
- UVA 10526 - Intellectual Property (后缀数组)
UVA 10526 - Intellectual Property 题目链接 题意:给定两个问题,要求找出第二个文本抄袭第一个文本的所有位置和长度,输出前k个,按长度从大到小先排,长度一样的按位置从小 ...
- F - Anti-Rhyme Pairs(rmq算法模板)(后缀数组算法模板)
点击打开链接 题目大意:通常押韵的两个词以相同的字符结尾.我们运用这个特性来规定反押韵的概念.反押韵是一对拥有近似开头的单词.一对单词的反押韵的复杂度被定义为两者都以之开头且最长的字符串S的长度.因此 ...
- 【uva10829-求形如UVU的串的个数】后缀数组+rmq or 直接for水过
题意:UVU形式的串的个数,V的长度规定,U要一样,位置不同即为不同字串 https://uva.onlinejudge.org/index.php?option=com_onlinejudge&am ...
- 寻找一个字符串的重复子串 后缀数组
什么是后缀数组 令字符串 S=S[1]S[2]...S[n]S=S[1]S[2]...S[n]{\displaystyle S=S[1]S[2]...S[n]} , S[i,j]S[i,j]{\dis ...
- 【2012百度之星/资格赛】H:用户请求中的品牌 [后缀数组]
时间限制: 1000ms 内存限制: 65536kB 描述 馅饼同学是一个在百度工作,做用户请求(query)分析的同学,他在用户请求中经常会遇到一些很奇葩的词汇.在比方说"johnsonj ...
- Boring counting HDU - 3518 (后缀数组)
Boring counting \[ Time Limit: 1000 ms \quad Memory Limit: 32768 kB \] 题意 给出一个字符串,求出其中出现两次及以上的子串个数,要 ...
- HDU4080 Stammering Aliens(二分 + 后缀数组)
题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=4080 Description Dr. Ellie Arroway has establish ...
- 后缀数组 + Hash + 二分 or Hash + 二分 + 双指针 求 LCP ---- 2017icpc 青岛 J Suffix (假题!!)
题目链接 题目大意: 就是给你n个串每个串取一个后缀,要求把串拼起来要求字典序最小!! sum_length_of_n≤5e5sum\_length\_of\_n\leq 5e5sum_length_ ...
- 后缀数组 ---- 2018~2019icpc焦作H题[后缀数组+st表+二分+单调栈]
题目链接 题目大意: 给出nnn个数,定义f[l,r]f[l,r]f[l,r]表示 区间[l,r][l,r][l,r]的最大值,求所有 子区间的最大值的和,要求相同的子区间只能算一次 比如数列 5 6 ...
最新文章
- CCNP-16 OSPF试验12(BSCI)
- python导入其他py文件-Python如何import其它.py文件及其函数
- 非静态内部类中为什么不能拥有静态成员?
- Java接口存在的意义以及如何解决菱形继承问题
- npm ERR! { Error: EPERM: operation not permitted, mkdir 'C:\Program Files\nodejs\node_cache\_locks'
- JS 关于(function( window, undefined ) {})(window)写法的理解
- $().each()和$.each()
- A20 init.sun7i.rc 文件
- RabbitMQ 入门 Helloworld
- Windows 安装JDK
- jQuery LightBox插件原理的简单实现
- PCIe扫盲——基于WinDriver快速开发PCIe驱动简明教程
- 51单片机开发板、usb写代码、pcb版
- CC2430 CC2530 AD转换分辨率之“争”
- matlab 最小割集(需手动分析排除)
- 新版win10的恢复语言栏设置
- nodejs php 模板,玩转nodejs
- 单例设计模式(饿汉式VS懒汉式)
- [转帖]国之魂,民之魂(硬骨头六连16勇士的最后一张照片)
- 原来手机还能当做扫描仪?安卓苹果都可以,纸质稿轻松电子化