[HDU4029]Distinct Sub-matrix/[JZOJ4683]矩阵
来源:互联网 发布:淘宝流量突然下降了 编辑:程序博客网 时间:2024/05/22 11:43
题目大意
给定一个
题目分析
一个很
然而这题我们可以使用一种更高的姿势水平玩哈希。枚举子矩阵宽度
问题变为求这个数组的本质不同的连续子序列个数,这是后缀数组和后缀自动机的经典问题。当然这题后缀自动机要使用
可能有点难理解,可以参考一下我的代码。
代码实现
#include <algorithm>#include <iostream>#include <cstdio>#include <cctype>using namespace std;typedef pair<int,int> P;#define mkp(a,b) make_pair(a,b)#define ft first#define sd secondconst int MOD=1004535809;const int P0=3873383;const int P1=9598609;const int N=120;const int M=120;const int S=N*M;int Ws[S],Wv[S],x[S],y[S],SA[S],rank[S],height[S];int n,m,cnt,len;int pw[2][M],rp[2][M];int hash[2][N][M];char s[N][M];P a[S];int quick_power(int x,int y){ int ret=1; for (;y;y>>=1,x=1ll*x*x%MOD) if (y&1) ret=1ll*ret*x%MOD; return ret;}void pre(){ pw[0][0]=1; for (int i=1;i<=m;i++) pw[0][i]=1ll*pw[0][i-1]*P0%MOD; rp[0][m]=quick_power(pw[0][m],MOD-2); for (int i=m-1;i>=0;i--) rp[0][i]=1ll*rp[0][i+1]*P0%MOD; for (int i=0;i<n;i++) { hash[0][i][0]=s[i][0]; for (int j=1;j<m;j++) hash[0][i][j]=(hash[0][i][j-1]+1ll*pw[0][j]*s[i][j])%MOD; } pw[1][0]=1; for (int i=1;i<=m;i++) pw[1][i]=1ll*pw[1][i-1]*P1%MOD; rp[1][m]=quick_power(pw[1][m],MOD-2); for (int i=m-1;i>=0;i--) rp[1][i]=1ll*rp[1][i+1]*P1%MOD; for (int i=0;i<n;i++) { hash[1][i][0]=s[i][0]; for (int j=1;j<m;j++) hash[1][i][j]=(hash[1][i][j-1]+1ll*pw[1][j]*s[i][j])%MOD; }}void build(int w){ len=0; for (int j=0;j<m-w+1;j++) { for (int i=0;i<n;i++) a[len++]=mkp(1ll*(hash[0][i][j+w-1]-(j?hash[0][i][j-1]:0)+MOD)%MOD*rp[0][j]%MOD,1ll*(hash[1][i][j+w-1]-(j?hash[1][i][j-1]:0)+MOD)%MOD*rp[1][j]%MOD); a[len++]=mkp(-(j+1),-(j+1)); }}bool cmp(int *r,int st1,int st2,int l){return st1+l>=len||st2+l>=len||r[st1]!=r[st2]||r[st1+l]!=r[st2+l];}bool compare(int x,int y){return a[x]<a[y];}void DA(){ int i,p,l,mx; for (i=0;i<len;i++) SA[i]=i; sort(SA,SA+len,compare); for (x[SA[0]]=p=0,i=1;i<len;i++) x[SA[i]]=(p+=a[SA[i]]!=a[SA[i-1]]); for (l=1;l<=len&&p!=len-1;l<<=1) { for (p=0,i=len-l;i<len;i++) y[p++]=i; for (i=0;i<len;i++) if (SA[i]>=l) y[p++]=SA[i]-l; for (i=0,mx=0;i<len;i++) mx=max(mx,Wv[i]=x[y[i]]); for (i=0;i<=mx;i++) Ws[i]=0; for (i=0;i<len;i++) Ws[Wv[i]]++; for (i=1;i<=mx;i++) Ws[i]+=Ws[i-1]; for (i=len-1;i>=0;i--) SA[--Ws[Wv[i]]]=y[i]; for (i=0;i<len;i++) y[i]=x[i],x[i]=0; for (x[SA[0]]=p=0,i=1;i<len;i++) x[SA[i]]=(p+=cmp(y,SA[i],SA[i-1],l)); } for (i=0;i<len;i++) rank[SA[i]]=i;}void getheight(){ for (int k=0,i=0,j;i<len;i++) { k?--k:k; if (!rank[i]) continue; for (j=SA[rank[i]-1];j+k<len&&i+k<len&&a[j+k]==a[i+k];) k++; height[rank[i]]=k; }}void count(){ for (int i=0;i<len;i++) if (a[SA[i]].ft>=0) cnt+=((SA[i]+1)/(n+1)*(n+1)+n-SA[i]-height[i]);}int main(){ freopen("matrix.in","r",stdin),freopen("matrix.out","w",stdout); scanf("%d%d",&n,&m); for (int i=0;i<n;i++) scanf("%s",s[i]); pre(); for (int w=1;w<=m;w++) build(w),DA(),getheight(),count(); printf("%d\n",cnt); fclose(stdin),fclose(stdout); return 0;}
0 0
- [HDU4029]Distinct Sub-matrix/[JZOJ4683]矩阵
- Distinct Sub-matrix HDOJ4416
- JZOJ4683 矩阵
- HDU 4029 Distinct Sub-matrix
- hdu 4029 Distinct Sub-matrix (后缀数组)
- 1009 Distinct Sub-matrix [2011上海网络赛]
- hdu 4029 Distinct Sub-matrix ( 后缀数组 + Hash )
- 【后缀数组+字符串hash】 HDOJ 4029 Distinct Sub-matrix
- HDU 4029 Distinct Sub-matrix(hash + 后缀数组)
- HDU 4029 Distinct Sub-matrix(哈希+后缀数组)
- HDU 4029 Distinct Sub-matrix(后缀数组+hash)
- HDU 4029 Distinct Sub-matrix(11年上海热身 后缀数组)
- HDU 4029 Distinct Sub-matrix 后缀数组 + Hash 2011年上海网络赛I题
- The Max Sum Of The Sub Matrix(子矩阵和最大)
- 矩阵Matrix
- Matrix 矩阵
- 矩阵(Matrix)
- Matrix矩阵
- Python 解决 :NameError: name 'reload' is not defined 问题
- HDU 2577(dp46)
- TCP-上传图片
- 《UNIX环境高级编程》十三守护进程读书笔记
- Eclipse中Maven工程缺少Maven Dependencies 的解决办法
- [HDU4029]Distinct Sub-matrix/[JZOJ4683]矩阵
- Python快速学习第五天
- adjusted rand index和adjusted mutual information score
- HDU 2870 (dp46)
- 数据有内在逻辑的表sql查询
- BST:有序数组构建成二叉搜索树
- 关于Ubuntu配置文件apache2 httpd.conf 位置
- android 中遇到得異常處理
- javaScript笔记(十八) DOM元素尺寸和位置