后缀数组求lcp(模版,st模版把
来源:互联网 发布:期货和股票的区别 知乎 编辑:程序博客网 时间:2024/05/21 09:12
算模版?,不过这东西,顺着思路很好写啊
题目读不懂。。。所以只有rmq和后缀数组是我写的,但是我也是想联系一下后缀数组求lcp,其实没法说吧,顺着st算法的理论写就行
不过为什么log求rmq_st的k,会wa,但是循环判断就不会?????
#include<cstdio>#include<cstring>#include<algorithm>#include<cstdlib>#include<cmath>#include<iostream>#define M(x) memset(x,0,sizeof(x))using namespace std;const int N=100005;int sa[N],c[N],t1[N],t2[N],s[N],height[N],rk[N],f[N][22],n;char ch[N];void clear(){M(sa);M(c);M(t1);M(t2);M(height);M(rk);M(f);M(s);}void build_sa() { int m=29,*x=t1,*y=t2; for (int i=0;i<m;i++) c[i]=0; for (int i=0;i<n;i++) c[x[i]=s[i]]++; for (int i=1;i<m;i++) c[i]+=c[i-1]; for (int i=n-1;i>=0;i--) sa[--c[x[i]]]=i; for (int k=1;k<=n;k<<=1) { int p=0; for (int i=n-k;i<n;i++) y[p++]=i; for (int i=0;i<n;i++) if (sa[i]>=k) y[p++]=sa[i]-k; for (int i=0;i<m;i++) c[i]=0; for (int i=0;i<n;i++) c[x[y[i]]]++; for (int i=1;i<m;i++) c[i]+=c[i-1]; for (int i=n-1;i>=0;i--) sa[--c[x[y[i]]]]=y[i]; swap(x,y); x[sa[0]]=0;p=1; for (int i=1;i<n;i++) x[sa[i]]=y[sa[i]]==y[sa[i-1]]&&y[sa[i]+k]==y[sa[i-1]+k]?p-1:p++; if (p>=n) break; m=p; } } void build_height() { int k=0; for (int i=0;i<n;i++) rk[sa[i]]=i; for (int i=0;i<n-1;i++) { if (k) k--; int j=sa[rk[i]-1]; while (s[j+k]==s[i+k]) k++; height[rk[i]]=k; } } void build_st(){for (int i=0;i<n;i++) f[i][0]=height[i];for (int k=1;(1<<k)<=n;k++)for (int i=0;i<n;i++)if (i+(1<<k)-1<n) f[i][k]=min(f[i][k-1],f[i+(1<<(k-1))][k-1]); }//预处理,第0名其实是不用算的,因为第0名是哨兵元素啊,我们需用的都是排在1~n-1之间的元素 int query_RMQ(int u,int v){int l=rk[u],r=rk[v];if (l>r) swap(l,r);l++;int k=0;while((1<<(1+k))<=r-l+1) k++;///为什么我用log过不了???,这里就是只要2^k乘2<=长度,那么就再把k++return min(f[l][k],f[r-(1<<k)+1][k]);}//rmq int change(int a) { if(a<10) return 1; else if(a<100) return 2; else if(a<1000) return 3; else if(a<10000) return 4; else if(a<100000) return 5; } int main () { while(scanf("%s",ch)!=EOF) { n=strlen(ch); for(int i=0;i<n;++i) s[i]=ch[i]-'a'+1; s[n++]=0; build_sa(); build_height(); build_st(); int q;scanf("%d",&q); long long len1=0,len2=0; for(int kk=1,u,v,lcp,preu=-1,prev=-1;kk<=q;++kk) { scanf("%d%d",&u,&v); if(preu>=0) { if(u==preu) lcp=n-u; else lcp=query_RMQ(u,preu); lcp=min(lcp,min(v-u,prev-preu)); len2+=change(lcp)+v-u-lcp; } else len2+=1+v-u; len1+=v-u+1; len2+=2; preu=u;prev=v; } cout<<len1<<' '<<len2<<endl; } return 0; }
0 0
- 后缀数组求lcp(模版,st模版把
- 【BZOJ4310】跳蚤,后缀数组+ST表求LCP+二分答案
- 后缀数组求LCP
- 后缀数组模版
- 后缀数组模版
- 后缀数组模版
- 后缀数组模版
- 后缀数组模版
- 后缀数组模版
- 后缀数组模版+注释
- hdu4691 后缀数组求lcp
- 后缀数组 倍增模版+D3C模版
- 后缀数组倍增算法模版
- 后缀数组(SA)模版
- 后缀数组的DC3模版【后缀数组】
- TYVJ 1860 后缀数组入门模版题
- 后缀数组模版O(N*2个log)求Sa[i]+字符串查找
- 后缀数组LCP + 二分
- network(poj1861)标准kruskal算法
- C++拷贝构造函数(20160812)
- AVPlayer视频播放
- JavaScript学习总结(十六)——Javascript闭包(Closure)
- Linux系列之nginx环境搭建(三)
- 后缀数组求lcp(模版,st模版把
- MySQL 索引详解
- #import 跟#include 的区别 #import<> 跟 #import""的区别
- window.onresize监听div和屏幕的改变
- 【2016】Android的Java面试/笔试基础题目
- Android Sqlite数据库的操作,其中包含不重复添加数据
- a便签hover设置颜色失效问题解决
- VS2010/MFC编程入门之十(对话框:设置对话框控件的Tab顺序)
- 光照贴图深入学习 Lightmapping In-Depth