【后缀数组】[UVA10829]L-Gap substring
来源:互联网 发布:河东区中山门淘宝街 编辑:程序博客网 时间:2024/06/06 17:02
题目
分析,这道题很显然要找两个相同的字串,也就是两个后缀公共前缀,很自然地可以想到,可以使用后缀数组。
所谓的L-Gap字串,就是两个相同的字串,中间间隔了g个字符,所以,我们枚举这两个字串的长度l,然后看0和l,l和l*2…..分别从这两个位置向前和向后匹配,匹配的长度减去l就是这个位置对答案的贡献。
#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>using namespace std;#define MAXN 50000*2#define MAXC 128#define Log 17int array[4][MAXN+10],st[MAXN+10][Log+1],g,*sa,*nsa,*rk,*nrk,b[MAXN+10],n,na,m,T,height[MAXN+10],ans,cnt;char s[MAXN+10];void Read(int &x){ char c; while(c=getchar(),c!=EOF) if(c>='0'&&c<='9'){ x=c-'0'; while(c=getchar(),c>='0'&&c<='9') x=x*10+c-'0'; ungetc(c,stdin); return; }}void cal_sa(){ rk=array[0],nrk=array[1],sa=array[2],nsa=array[3]; int i,k; rk[n]=nrk[n]=-1; memset(b,0,sizeof b); for(i=0;i<n;i++) b[s[i]]++; for(i=1;i<=MAXC;i++) b[i]+=b[i-1]; for(i=0;i<n;i++) sa[--b[s[i]]]=i; for(rk[sa[0]]=0,i=1;i<n;i++){ rk[sa[i]]=rk[sa[i-1]]; if(s[sa[i]]!=s[sa[i-1]]) rk[sa[i]]++; } for(k=1;rk[sa[n-1]]<n-1;k<<=1){ for(i=0;i<n;i++) b[rk[sa[i]]]=i; for(i=n-1;i>=0;i--) if(sa[i]>=k) nsa[b[rk[sa[i]-k]]--]=sa[i]-k; for(i=n-k;i<n;i++) nsa[b[rk[i]]--]=i; for(nrk[nsa[0]]=0,i=1;i<n;i++){ nrk[nsa[i]]=nrk[nsa[i-1]]; if(rk[nsa[i]]!=rk[nsa[i-1]]||rk[nsa[i]+k]!=rk[nsa[i-1]+k]) nrk[nsa[i]]++; } swap(sa,nsa); swap(rk,nrk); }}void read(){ Read(g); scanf("%s",s); na=strlen(s); s[na]='$'; int i; for(i=1;i<=na;i++) s[na+i]=s[na-i]; n=(na<<1)|1; s[n]=0;}void cal_height(){ int i,j,k=0; for(i=0;i<n;i++) if(!rk[i]) height[rk[i]]=0; else{ if(k) k--; for(j=sa[rk[i]-1];s[i+k]==s[j+k];k++); height[rk[i]]=k; }}void prepare(){ int i,j; for(i=0;i<n;i++) st[i][0]=height[i]; for(j=1;j<=Log;j++) for(i=0;i<n;i++) if(i+(1<<(j-1))<n) st[i][j]=min(st[i][j-1],st[i+(1<<(j-1))][j-1]);}int Get_st(int rk1,int rk2){ if(rk1>rk2) swap(rk1,rk2); int t=log2(rk2-rk1); return min(st[rk1+1][t],st[rk2-(1<<t)+1][t]);}void solve(){ int i,j,k,t; for(i=1;i<na;i++){ for(j=0;j<na&&j+i+g<na;j+=i){ k=i+j+g; t=min(Get_st(rk[j],rk[k]),i); t+=min(Get_st(rk[n-j],rk[n-k]),i-1); ans+=max(t-i+1,0); } }}int main(){ Read(T); while(T--){ memset(st,0,sizeof st); ans=0; read(); cal_sa(); cal_height(); prepare(); solve(); printf("Case %d: %d\n",++cnt,ans); }}
0 0
- 【后缀数组】[UVA10829]L-Gap substring
- uva10829 - L-Gap Substrings 后缀数组+RMQ
- uva10829 L-Gap Substrings
- UVA 10829 - L-Gap Substrings(后缀数组)
- uva 10829 - L-Gap Substrings(后缀数组)
- UVA 10829 L-Gap Substrings 后缀数组
- 后缀数组(好)uva10829
- UVA 10829 L-Gap Substrings(后缀数组好题)
- UVa 10829 - L-Gap Substrings (后缀数组)
- UVA 10829 L-Gap Substrings(后缀数组)
- UVA 10829 L-Gap Substrings(后缀数组+枚举区间优化)
- UVA 10829 L-Gap Substrings (后缀数组+RMQ)
- HDU5769 Substring 后缀数组
- POJ3693Maximum repetition substring【后缀数组】
- HDU 5769 Substring(后缀数组)
- hdu-5769-Substring-后缀数组
- hdu 5769 Substring 后缀数组
- HDU 5769 Substring(后缀数组)
- 查看SQL-Server数据库所有触发器信息
- Android开发之在OS X EI Capitan上搭建Android开发环境
- 算法复习——LazyTag
- Unity动态更换外部Texturte和网络文件
- 今天开始正式加入CSDN大家庭!
- 【后缀数组】[UVA10829]L-Gap substring
- 深入分析JavaWeb Item35 -- 过滤器Filter学习
- Linux下,强制删除oracle10g安装文件后再重装
- Untiy鼠标控制角色转向
- 好奇心害死猫——codevs3123超大整数乘法
- 【杭电2015年12月校赛D】【水题 最小生成树】Happy Value 最小生成树裸题
- ios 字符串大小写转换代码
- TeamTalk部署教程
- Unity调用外部EXE和启动浏览器(手机端也可以启动IE内核)