[ACDream 1430]SETI 后缀数组
2014-10-06 21:57
351 查看
题目链接:http://acdream.info/problem?pid=1430
题目大意:给你一个长度不超过10000的字符串,问你出现过两次或两次以上的不重叠的子串有多少个。
后缀数组计算出height数组出来,然后分组。
如果没有分在一组的话代表两个的前缀是不相同的。于是就可以暴力搞了。
代码:
View Code
题目大意:给你一个长度不超过10000的字符串,问你出现过两次或两次以上的不重叠的子串有多少个。
后缀数组计算出height数组出来,然后分组。
如果没有分在一组的话代表两个的前缀是不相同的。于是就可以暴力搞了。
代码:
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long LL; const int maxn = 1e5+100; int wa[maxn],wb[maxn],wv[maxn],ws[maxn]; int sa[maxn],r[maxn]; int rank[maxn],height[maxn]; char s[maxn]; int cmp(int *r,int a,int b,int l){ return r[a]==r[b]&&r[a+l]==r[b+l]; } void da(int *r,int *sa,int n,int m){ int i,j,p,*x=wa,*y=wb,*t; for(i=0;i<m;i++) ws[i] = 0; for(i=0;i<n;i++) ws[x[i]=r[i]]++; for(i=1;i<m;i++) ws[i]+= ws[i-1]; for(i=n-1;i>=0;i--) sa[--ws[x[i]]] = i; for(j=1,p=1;p<n;j*=2,m=p){ for(p=0,i=n-j;i<n;i++) y[p++] = i; for(i=0;i<n;i++) if(sa[i]>=j) y[p++] = sa[i]-j; for(i=0;i<n;i++) wv[i] = x[y[i]]; for(i=0;i<m;i++) ws[i] = 0; for(i=0;i<n;i++) ws[wv[i]]++; for(i=1;i<m;i++) ws[i]+=ws[i-1]; for(i=n-1;i>=0;i--) sa[--ws[wv[i]]] = y[i]; for(t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1;i<n;i++) x[sa[i]] = cmp(y,sa[i-1],sa[i],j)?p-1:p++; } } void calheight(int *r,int *sa,int n){ int i,j,k=0; for(i=1;i<=n;i++) rank[sa[i]]=i; for(i=0;i<n;height[rank[i++]]=k) for(k?k--:0,j=sa[rank[i]-1];r[i+k]==r[j+k];k++); } int main(){ gets(s); int len = strlen(s); for(int i=0;i<len;i++){ r[i] = s[i] - 'a' + 1; } da(r,sa,len+1,100); calheight(r,sa,len); // for(int i=1;i<=len;i++){ // printf("%d ",sa[i]); // } // puts(""); // for(int i=2;i<=len;i++) printf("%d ",height[i]); puts(""); int ans = 0; for(int k=1;k<=len;k++){ int maxn = sa[1] , minn = sa[1]; int q = 0; // printf("now k=%d\n",k); for(int i=2;i<=len+1;i++){ if( height[i]<k||i==len+1 ){ if( maxn-minn>=k ) ans++; maxn = minn = sa[i]; // printf("i=%d sa[i]=%d maxn = %d minn = %d\n",i,sa[i],maxn,minn); } else if(i<=len){ maxn = max(sa[i],maxn); minn = min(sa[i],minn); } } // printf("k=%d q=%d\n",k,q); // q = 0; } printf("%d\n",ans); return 0; }
View Code
相关文章推荐
- Acdream 1430 SETI(后缀数组)
- ACdream 1430 SETI 后缀自动机
- ACdream 1430 SETI
- acdream 1430 SETI 后缀数组+height分组
- ACdream 1430 SETI 后缀自动机/后缀数组 不重叠子串的个数
- ACdream 1430——SETI——————【后缀数组,不重叠重复子串个数】
- acdream 1430 SETI 后缀数组+height分组
- SETI--后缀数组
- SETI ACdream - 1430 后缀自动机求不相交子串
- acdream 1427后缀数组
- U R Seti?
- SPOJ 694(后缀数组)
- zoj 1430 || poj 1697 The Erythea Campaign
- poj2774(后缀数组)
- HDU 2328 Corporate Identity 后缀数组
- poj 3450 Corporate Identity (后缀数组)
- POJ-1430 Binary Stirling Numbers 组合数学
- 后缀数组
- 后缀数组模板
- Acdream 1015 Double Kings 搜索