UVALive4513 Stammering Aliens(哈希法,后缀数组)
来源:互联网 发布:如何编写安卓软件 编辑:程序博客网 时间:2024/06/05 08:32
题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=12580
【思路】
求出现次数不小于k次的最长可重复子串和最后的出现位置。
法一:
后缀数组,二分长度,划分height。时间复杂度为O(nlogn)
法二:
Hash法。构造字符串的hash函数,二分长度,求出hash(i,L)后排序,判断是否存在超过k个相同hash 值得块即可。时间为O(nlog2n).
注意划分height一定要精确且如果m=1需要特判(对于该模板来说)。
【代码1】
1 //193ms 2 #include<cstdio> 3 #include<cstring> 4 #include<iostream> 5 using namespace std; 6 7 const int maxn = 80000+10; 8 9 int s[maxn];10 int sa[maxn],c[maxn],t[maxn],t2[maxn];11 void build_sa(int m,int n) {12 int i,*x=t,*y=t2;13 for(i=0;i<m;i++) c[i]=0;14 for(i=0;i<n;i++) c[x[i]=s[i]]++;15 for(i=1;i<m;i++) c[i]+=c[i-1];16 for(i=n-1;i>=0;i--) sa[--c[x[i]]]=i;17 for(int k=1;k<=n;k<<=1) {18 int p=0;19 for(i=n-k;i<n;i++) y[p++]=i;20 for(i=0;i<n;i++) if(sa[i]>=k) y[p++]=sa[i]-k;21 for(i=0;i<m;i++) c[i]=0;22 for(i=0;i<n;i++) c[x[y[i]]]++;23 for(i=0;i<m;i++) c[i]+=c[i-1];24 for(i=n-1;i>=0;i--) sa[--c[x[y[i]]]]=y[i];25 swap(x,y);26 p=1; x[sa[0]]=0;27 for(i=1;i<n;i++) 28 x[sa[i]]=y[sa[i]]==y[sa[i-1]] && y[sa[i]+k]==y[sa[i-1]+k]?p-1:p++;29 if(p>=n) break;30 m=p;31 }32 }33 int rank[maxn],height[maxn];34 void getHeight(int n) {35 int i,j,k=0;36 for(i=0;i<=n;i++) rank[sa[i]]=i;37 for(i=0;i<n;i++) {38 if(k) k--;39 j=sa[rank[i]-1];40 while(s[j+k]==s[i+k]) k++;41 height[rank[i]]=k;42 }43 }44 int limit,n,pos;45 bool can(int L) { //一定要注意划分height数组的准确性 46 pos=-1;47 int cnt=1,mx=sa[1];48 for(int i=2;i<=n;i++) {49 mx=max(mx,sa[i]);50 if(height[i]<L) cnt=1,mx=sa[i];51 else {52 if(++cnt>=limit) pos=max(pos,mx);53 }54 }55 return pos>=0;56 }57 58 char expr[maxn];59 int main() {60 //freopen("in.in","r",stdin);61 //freopen("out.out","w",stdout);62 while(scanf("%d",&limit)==1 && limit) {63 scanf("%s",expr);64 n=strlen(expr);65 for(int i=0;i<n;i++) s[i]=expr[i]; s[n]=0;66 67 build_sa('z'+1,n+1);68 getHeight(n);69 70 if(limit==1) { printf("%d 0\n",n); continue; }71 int L=1,R=n+1;72 while(L<R) {73 int M=L+(R-L+1)/2;74 if(can(M)) L=M; else R=M-1;75 }76 if(!can(L)) printf("none\n");77 else printf("%d %d\n",L,pos);78 }79 return 0;80 }
【代码2】
1 //1628ms 2 #include<cstdio> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm> 6 using namespace std; 7 8 typedef unsigned long long ULL; 9 const int maxn = 80000+10;10 const int x = 233;11 12 ULL hash[maxn],xp[maxn],H[maxn];13 int m,n;14 char s[maxn];15 16 int cmp(const int& a,const int& b) {17 return hash[a]<hash[b] || (hash[a]==hash[b] && a<b);18 }19 int pos,rank[maxn];20 bool can(int L) {21 pos=-1;22 for(int i=0;i<n-L+1;i++) hash[i]=H[i]-H[i+L]*xp[L],rank[i]=i;23 sort(rank,rank+n-L+1,cmp);24 int cnt=0;25 for(int i=0;i<n-L+1;i++) {26 if(!i || hash[rank[i]]!=hash[rank[i-1]]) cnt=0;27 if(++cnt>=m) pos=max(pos,rank[i]);28 }29 return pos>=0;30 }31 32 int main() {33 //freopen("in.in","r",stdin);34 //freopen("outr.out","w",stdout);35 while(scanf("%d",&m)==1 && m) {36 scanf("%s",s);37 n=strlen(s);38 39 H[n]=0,xp[0]=1;40 for(int i=n-1;i>=0;i--) H[i]=H[i+1]*x+s[i]-'a';41 for(int i=1;i<=n;i++) xp[i]=xp[i-1]*x;42 43 if(!can(1)) printf("none\n");44 else {45 int L=1,R=n+1;46 while(L<R) {47 int M=L+(R-L+1)/2;48 if(can(M)) L=M; else R=M-1;49 }50 can(L);51 printf("%d %d\n",L,pos);52 }53 }54 return 0;55 }
0 0
- UVALive4513 Stammering Aliens(哈希法,后缀数组)
- HDU 4080 Stammering Aliens(后缀数组)
- poj 3882(Stammering Aliens) 后缀数组 或者 hash
- HDU 4080 Stammering Aliens (后缀数组 + 二分答案)
- HDU 4080 Stammering Aliens(后缀数组+二分)
- 后缀数组,LCP(Stammering Aliens,LA 4513)
- ZOJ3395 Stammering Aliens 二分+后缀数组
- hdu 4080 Stammering Aliens - 后缀数组
- HDU 4080 Stammering Aliens && 后缀数组
- UVALive - 4513 Stammering Aliens(后缀数组模板)
- UVA 12206 - Stammering Aliens(后缀数组)
- [后缀数组+二分] hdu 4080 Stammering Aliens
- hdu4080---Stammering Aliens(后缀数组+二分)
- UVA 12206 Stammering Aliens(后缀数组+二分)
- POJ 3882 Stammering Aliens 后缀数组height应用
- UVALive 4513 (LA 4513) Stammering Aliens 后缀数组 或 hash
- UVALive 4513 Stammering Aliens (hash+二分 or 后缀数组)
- Hdu 4080 & Poj 3882 Stammering Aliens (后缀数组 可重叠k次最长重复子串)
- bzoj3223 Tyvj 1729 文艺平衡树(Splay Tree+区间翻转)
- 1021. 个位数统计
- bzoj1251 序列终结者(Splay Tree+懒惰标记)
- 【学习笔记】matlab中 pushbutton的buttondownfcn和callback函数有什么区别?
- bzoj1208 [HNOI2004]宠物收养所(STL,Treap)
- UVALive4513 Stammering Aliens(哈希法,后缀数组)
- bzoj1503 [NOI2004]郁闷的出纳员(名次树+懒惰标记)
- bzoj 1056 [HAOI2008]排名系统(1862 [Zjoi2006]GameZ游戏排名系统)
- bzoj2730 [HNOI2012]矿场搭建 (UVAlive5135 Mining Your Own Business)
- UVAlive3523 Knights of the Round Table(bcc)
- 隐式启动Activity
- UVAlive11324 The Largest Clique(scc+dp)
- IllegalStateException: Can not perform this action after onSaveInstanceState
- lightoj 1145 - Dice (I) 前缀和优化DP