HDU 6194 String String String 后缀数组 正好出现K次的子串个数 CSU1632 至少出现2次的子串个数
来源:互联网 发布:mysql云数据库购买 编辑:程序博客网 时间:2024/05/29 09:38
求正好出现K次的子串个数。
对于
对于
最后模板打错,WA到怀疑人生。。
#include <iostream>#include <bits/stdc++.h>using namespace std;typedef long long LL;const int MAXN = 1e5+1000;char s[MAXN];int num[MAXN],wa[MAXN],wb[MAXN],wv[MAXN],wd[MAXN],rk[MAXN],sa[MAXN],height[MAXN],n,minl[MAXN][20],k;int cmp(int *r,int a,int b,int l){ return r[a]==r[b] && r[a+l]==r[b+l];}void SA(int *r,int n){ int *x=wa,*y=wb,m=0; for (int i=0;i<n;i++) m=max(m,r[i]+1); for (int i=0;i<m;i++) wd[i]=0; for (int i=0;i<n;i++) ++wd[x[i]=r[i]]; for (int i=1;i<m;i++) wd[i]+=wd[i-1]; for (int i=n-1;i>=0;i--) sa[--wd[x[i]]]=i; int p=1; for (int j=1;p<n;j<<=1,m=p) { p=0; for(int i=n-j; i<n; ++i) y[p++]=i; for(int i=0; i<n; ++i) if(sa[i]>=j) y[p++]=sa[i]-j; for(int i=0; i<n; ++i) wv[i]=x[y[i]]; for (int i=0;i<m;i++) wd[i]=0; for (int i=0;i<n;i++) ++wd[wv[i]]; for (int i=1;i<m;i++) wd[i]+=wd[i-1]; for (int i=n-1;i>=0;i--) sa[--wd[wv[i]]]=y[i]; swap(x,y); x[sa[0]]=0;p=1; for (int i=1;i<n;i++) x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++; } for (int i=1;i<n;i++) rk[sa[i]]=i; int k=0; for (int i=0;i<n-1;height[rk[i++]]=k) { if (k)--k; for (int j=sa[rk[i]-1];r[i+k]==r[j+k];++k); }}void initRMQ(){ int l=int(log(n)/log(2.0)); for (int i=1;i<=n;i++) minl[i][0]=height[i]; for (int j=1;j<=l;j++) for (int i=1;i+(1<<(j-1)) <=n ;i++) minl[i][j] = min(minl[i][j-1] , minl[i+(1<<(j-1))][j-1]);}int askRMQ(int l,int r){ int k=int(log(r-l+1)/log(2)); return min(minl[l][k] , minl[r-(1<<k)+1][k]);}void sov(){ LL ans=0; if (k>=2) { int l=2,r=k; while (r<=n) { LL tmp=askRMQ(l,r) - max(height[l-1],height[r+1]); if (tmp > 0 ) ans+=tmp; l++;r++; } } else { for (int i=1;i<=n;i++) ans += n-sa[i]-max(height[i],height[i+1]); } printf("%lld\n",ans);}int main(){ int t; scanf("%d",&t); while (t--) { memset(sa,0,sizeof sa); memset(rk,0,sizeof rk); memset(height,0,sizeof height); scanf("%d%s",&k,s); int len=strlen(s); n=len; for (int i=0;i<n;i++) num[i] =s[i]; num[n]=0; SA(num,n+1); initRMQ(); sov(); } return 0;}
CSU1632
求至少出现两次的子串个数。
同样的,出现两次,我们先维护一个长度为1的区间,如果是求正好两次,那么就是
从这两题里我们可以看出,如果只减去前面的,那么求的就是至少K次。如果两边都减,那么就是正好K次。
阅读全文
0 0
- HDU 6194 String String String 后缀数组 正好出现K次的子串个数 CSU1632 至少出现2次的子串个数
- 2017沈阳网络赛 1001 HDU 6194 string string string(后缀自动机 出现k次的子串个数)
- hdu 3518 ( 后缀数组 至少出现两次的不重叠子串个数)
- poj 3882 后缀数组 求一个串至少出现k次的最长重复子串的长度
- PKU 3261(求最长的至少出现k次的子串,后缀数组+二分枚举)
- poj 3261 Milk Patterns (后缀数组 至少出现k次的可重叠最长重复子串)
- hdu 4080 Stammering Aliens ( 后缀数组 求最长的至少出现m次可重叠子串)
- hdu 6194 恰好出现k次的子串
- hdu5056(找相同字母不出现k次的子串个数)
- POJ3261 Milk Patterns,后缀数组, 出现k次的重复子串
- POJ 3261 Milk Patterns 最长出现k次的子串长度(后缀数组)
- hdoj String 5672 (字符串模拟)求至少有k个不重复的字符的子串个数
- poj3261(求至少出现k次的可重叠的子串的长度)
- poj 3261 后缀数组 找重复出现k次的子串(子串可以重叠)
- HDU 3518 Boring counting(后缀数组啊 求字符串中不重叠的重复出现至少两次的子串的个数)
- Hdu 3518 Boring counting (出现2次及以上且不重叠的子串的个数)
- poj 3294 后缀数组求至少在k个串中出现的公共子串
- Poj 3294 Life Forms (后缀数组 在n个串中出现k次的最长公共子串并输出)
- 泛型方法
- eclipse如何安装java decompiler反编译插件
- [Codeforces Round #436 (Div. 2)]
- 解决 Windows 下 scrapy 第三方库无法安装问题
- 整理一下eclipse的快捷键
- HDU 6194 String String String 后缀数组 正好出现K次的子串个数 CSU1632 至少出现2次的子串个数
- Decoding Lab: Understanding a Secret Message
- 第一篇博客
- [cnblogs镜像]Unity 动画系统(Mecanim) 术语及翻译 表格
- 9.26shopee面试
- c++ static
- [cnblogs镜像]Unity 动画系统(Mecanim)的组成结构
- tomcat7-maven-plugin的使用
- Java300StudyNote(7)-JVM核心机制(2)-初始化时机-类的主动引用、被动引用、静态初始化块执行顺序问题