后缀数组(入门)——51nod1732 51nod婚姻介绍所
来源:互联网 发布:php语言 编辑:程序博客网 时间:2024/04/28 21:11
题面:51nod1732
要死的SA!
今天入门后缀数组,具体的后缀数组教程网上也很多
这里推荐一个:传送门,讲的还不错
听说这题可以用hash直接过,不过的确是SA的入门题哦
这题要我们求的是串s对于x,y的最大公共前缀
掌握SA的基本操作之后这题的答案就是min(Height[rank[x]]~Height[rank[y]])
然后可以用线段树维护一下,还有读入输出优化,否则T了QAQ
#include <cstdio>#include <algorithm>#include <cmath>#include <cstring>#include <iostream>#include <ctime>#include <map>#include <queue>#include <cstdlib>#include <string>#include <climits>#include <set>using namespace std;inline int read(){ int k=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){k=k*10+ch-'0';ch=getchar();} return k*f;}inline void write(int x){if(x>=10)write(x/10);putchar(x%10+'0');}inline void writeln(int x){write(x);puts("");}int n,m,rank[100001],sa[100001],a[100001],rank1[100001],h[100001];int ton[100001],t[400001];char s[100001];inline void build(int l,int r,int nod){ if(l==r){t[nod]=h[l];return;} int mid=l+r>>1; build(l,mid,nod*2);build(mid+1,r,nod*2+1); t[nod]=min(t[nod*2],t[nod*2+1]);}inline int ssum(int l,int r,int i,int j,int nod){ if(l>=i&&r<=j)return t[nod]; int mid=l+r>>1,ans=1e9; if(i<=mid)ans=min(ans,ssum(l,mid,i,j,nod*2)); if(j>mid)ans=min(ans,ssum(mid+1,r,i,j,nod*2+1)); return ans;}inline void Sort(){ for(int i=0;i<=m;i++)ton[i]=0; for(int i=1;i<=n;i++)ton[rank[rank1[i]]]++; for(int i=1;i<=m;i++)ton[i]+=ton[i-1]; for(int i=n;i;i--)sa[ton[rank[rank1[i]]]--]=rank1[i];}int main(){ n=read();scanf("%s",s+1); for(int i=1;i<=n;i++)a[i]=s[i]; for(int i=1;i<=n;i++)rank[i]=a[i],rank1[i]=i; m=127;Sort(); for(int i=1,j,p=1;p<n;i*=2,m=p){ for(p=0,j=n-i+1;j<=n;j++)rank1[++p]=j; for(j=1;j<=n;j++)if(sa[j]>i)rank1[++p]=sa[j]-i; Sort();swap(rank,rank1);rank[sa[1]]=p=1; for(j=2;j<=n;j++)rank[sa[j]]=(rank1[sa[j]]==rank1[sa[j-1]]&&rank1[sa[j]+i]==rank1[sa[j-1]+i])?p:++p; } for(int i=1,j=0,k=0;i<=n;h[rank[i++]]=k) for(k=k?k-1:k,j=sa[rank[i]-1];a[i+k]==a[j+k];++k); build(1,n,1); int Q=read(); while(Q--){ int x=read()+1,y=read()+1; if(x==y){writeln(n-x+1);continue;} int xx=rank[x],yy=rank[y]; if(xx>yy)swap(xx,yy);xx++; writeln(ssum(1,n,xx,yy,1)); } return 0;}
阅读全文
1 0
- 后缀数组(入门)——51nod1732 51nod婚姻介绍所
- 后缀数组——51nod 1732 51nod婚姻介绍所
- 51nod 1732 51nod婚姻介绍所 后缀数组 + rmq
- 51 nod 1732 51nod婚姻介绍所(后缀数组||DP)
- 51nod 1732 51nod婚姻介绍所(LCS变形)
- 51nod 1732 51nod婚姻介绍所
- 51Nod-1732-51Nod婚姻介绍所
- 51nod 1732 51nod婚姻介绍所
- 51nod 1732 51nod婚姻介绍所
- 【51nod】1732 51nod婚姻介绍所
- 51Nod 1732 51nod婚姻介绍所
- 51NOD 1089 后缀数组 或 manacher
- 51 nod 1292 字符串中的最大值 V2(后缀数组)
- 后缀数组入门题——2323后缀排序
- 后缀数组 (入门模板)
- 51Nod- 1280-前缀后缀集合(map)
- 51Nod 1292 字符串中的最大值 V2 后缀数组 + 单调栈
- 51nod 1440 迈克打电话 后缀数组+可持久化线段树+二分
- 【Unity3D ugui】使用艺术字
- 实现ListView右侧的快速拖动条
- duplicate symbol _OBJC_CLASS_$_XXX in
- 进程间通信——管道
- 【python】time,datetime,string相互转换
- 后缀数组(入门)——51nod1732 51nod婚姻介绍所
- 547.两数组的交
- jqGrid 5.x 参数详解
- windows下快速使用LightGBM安装教程(已编译)
- jvm工作原理
- 用javascript源码打印页面
- Entity FrameWork介绍
- 线程死锁
- 链表插入排序