HDU 4029 Distinct Sub-matrix
2015-03-30 16:14
309 查看
先将矩阵hash成一维的,然后用后缀数组求不同子串个数
具体hash方法:
先介绍将字符串hash成整数的方法,设s为hash值,则对于第i个字符,hash值*base+字符串的ASC编码。其中base为种子值,最好取质数
这样,对于每个矩阵,我们就有了将其hash成一维的方法了,即对每一行,求得其hash值,存在首字符的位置上。
将二维化为一维之后,就变成了求多个字符串的不同子串个数,这个用后缀数组解决
具体hash方法:
先介绍将字符串hash成整数的方法,设s为hash值,则对于第i个字符,hash值*base+字符串的ASC编码。其中base为种子值,最好取质数
这样,对于每个矩阵,我们就有了将其hash成一维的方法了,即对每一行,求得其hash值,存在首字符的位置上。
将二维化为一维之后,就变成了求多个字符串的不同子串个数,这个用后缀数组解决
#include<stdio.h> #include<algorithm> #include<string.h> #include<map> using namespace std; #define N 130 #define L 130*130 typedef unsigned long long ull; typedef unsigned int uint; uint base=131; char s ; ull h ;//h[i][j]表示s[i][j],s[i][j+1].....s[i][j+w-1]这个字符串的hash值 int st[L]; int wa[L],wb[L],wv[L],ws[L];//wa:第一关键字(即临时的Rank) wb:第二关键字 ws:计数排序的hash数组 wv:用于存放因不断计数排序产生的新值 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; 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){//这里对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]; swap(x,y); for(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++; } return; } int sa[L],Rank[L],height[L]; 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++); return; } int main(){ #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); #endif int t,n,m; scanf("%d",&t); int cas=1; while(t--){ scanf("%d%d",&n,&m); ull ans=0; for(int i=0;i<n;i++) scanf("%s",s[i]); memset(h,0,sizeof(h)); for(int w=1;w<=m;w++){//子串宽度 int max=1,l=0; map<ull,int> map; map.clear(); for(int i=0;i<n;i++){//位置 for(int j=0;j+w-1<m;j++){//位置 h[i][j]=h[i][j]*base+s[i][j+w-1]-'A'; if(map.find(h[i][j])==map.end()) map.insert(make_pair(h[i][j],max++));//为了减少复杂度,要将hash值map到1-max之间 } } for(int j=0;j+w-1<m;j++) { for(int i=0;i<n;i++) { st[l++]=map[h[i][j]]; } st[l++]=max++;//将串连接起来,并加分隔符 } st[l]=0; da(st,sa,l+1,max); calheight(st,sa,l); ull tmp=n*(n+1)/2*(m-w+1); for(int i=1;i<=l;i++) tmp-=height[i]; ans+=tmp; } printf("Case #%d: %I64u\n",cas++,ans); } return 0; }
相关文章推荐
- HDU 4029 Distinct Sub-matrix(后缀数组+hash)
- hdu 4029 Distinct Sub-matrix (后缀数组)
- HDU 4029 Distinct Sub-matrix(11年上海热身 后缀数组)
- HDU 4029 Distinct Sub-matrix [后缀数组]
- HDU 4029 Distinct Sub-matrix(hash + 后缀数组)
- HDU 4029 Distinct Sub-matrix(哈希+后缀数组)
- HDU 4029 Distinct Sub-matrix 后缀数组 + Hash 2011年上海网络赛I题
- HDU 4029 Distinct Sub-matrix(后缀数组)
- 【后缀数组+字符串hash】 HDOJ 4029 Distinct Sub-matrix
- HDU 2686 Matrix 费用流
- HDU 2119 Matrix 简单二分匹配
- hdu(5612)——Baby Ming and Matrix games
- HDU 5671 Matrix——BestCoder Round #81(div.1 div.2)
- hdu 5015 233 Matrix 矩阵快速幂
- hdu_5671_Matrix(BestCoder Round #81 (div2))
- 组合数(Lucas定理) + 快速幂 --- HDU 5226 Tom and matrix
- Matrix Again HDU 3376 最大费用最大流
- HDU 5015 233 Matrix
- hdu 2686 Matrix 双线程dp
- hdu 3666 THE MATRIX PROBLEM【差分约束系统】