HDU 4029 Distinct Sub-matrix(哈希+后缀数组)
来源:互联网 发布:windows 7库 快捷方式 编辑:程序博客网 时间:2024/05/22 16:05
题意:给出一个矩阵(n,m<=128),求出这个矩阵不同的子矩阵的数量。
思路:首先容易想到对这个矩阵的每一个子矩阵进行哈希然后找出不重复的,但是这样做光是枚举所有矩阵复杂度就会达到O(n^4),更不用说空间复杂度无法承受了。
考虑类似于求矩阵最大子矩阵和的方法,将原矩阵的每一列的任意子序列哈希,即用hash[i][j][k]表示原矩阵第i列从第j行到第k行的哈希值。
有了这个以后我们可以枚举子矩阵的行数h,然后对于所有h行的子矩阵我们将哈希值离散化然后插入到后缀数组中,注意不同行的哈希值之间要用一个没出现的数字分隔开,剩下的就是后缀数组求不同的子串数量。
#include<cstdio>#include<cstring>#include<cmath>#include<cstdlib>#include<iostream>#include<algorithm>#include<vector>#include<map>#include<queue>#include<stack>#include<string>#include<map>#include<set>#include<ctime>#define eps 1e-6#define LL long long#define ULL unsigned long long#define pii pair<int, int>//#pragma comment(linker, "/STACK:1024000000,1024000000")using namespace std;const int MAXN = 150; const ULL base = 131;int n, m;ULL Hash[MAXN][MAXN][MAXN];ULL G[MAXN][MAXN];struct SuffixArray { int s[MAXN*MAXN]; /// 原始字符数组(最后一个字符应必须是0,而前面的字符必须非0) int sa[MAXN*MAXN]; // 后缀数组,sa[0]一定是n-1,即最后一个字符 int rank[MAXN*MAXN]; // 名次数组 int height[MAXN*MAXN]; // height数组 int t[MAXN*MAXN], t2[MAXN*MAXN], c[MAXN*MAXN]; // 辅助数组 int n; // 字符个数 void clear() { n = 0; memset(sa, 0, sizeof(sa)); } /// m为最大字符值加1。!!! 调用之前需设置好s和n void build_sa(int m) { int i, *x = t, *y = t2; for(i = 0; i < m; i++) c[i] = 0; for(i = 0; i < n; i++) c[x[i] = s[i]]++; for(i = 1; i < m; i++) c[i] += c[i-1]; for(i = n-1; i >= 0; i--) sa[--c[x[i]]] = i; for(int k = 1; k <= n; k <<= 1) { int p = 0; for(i = n-k; i < n; i++) y[p++] = i; for(i = 0; i < n; i++) if(sa[i] >= k) y[p++] = sa[i]-k; for(i = 0; i < m; i++) c[i] = 0; for(i = 0; i < n; i++) c[x[y[i]]]++; for(i = 0; i < m; i++) c[i] += c[i-1]; for(i = n-1; i >= 0; i--) sa[--c[x[y[i]]]] = y[i]; swap(x, y); p = 1; x[sa[0]] = 0; for(i = 1; i < n; i++) x[sa[i]] = y[sa[i-1]]==y[sa[i]] && y[sa[i-1]+k]==y[sa[i]+k] ? p-1 : p++; if(p >= n) break; m = p; } } void build_height() { int i, j, k = 0; for(i = 0; i < n; i++) rank[sa[i]] = i; for(i = 0; i < n; i++) { if(k) k--; j = sa[rank[i]-1]; while(s[i+k] == s[j+k]) k++; height[rank[i]] = k; } } } sa;int pos[MAXN*MAXN];void addchar(int x, int p) {pos[sa.n] = p;sa.s[sa.n++] = x;}map<ULL, int> lsh;int tot;int ls(ULL x) {if(lsh[x]) return lsh[x];return lsh[x] = ++tot;}int main() { //freopen("input.txt", "r", stdin);int T; cin >> T;int kase = 0;while(T--) {cin >> n >> m;for(int i = 1; i <= n; i++) {char tmp[MAXN];scanf("%s", tmp);for(int j = 1; j <= m; j++) G[i][j] = tmp[j-1] - 'A' + 1; }for(int i = 1; i <= m; i++) {for(int j = 1; j <= n; j++) {for(int k = j; k <= n; k++) {Hash[i][j][k] = Hash[i][j][k-1] * base + G[k][i];}}}LL ans = 0;for(int h = 1; h <= n; h++) {sa.clear();lsh.clear();tot = 0;int shit = n * m + 1;for(int i = 1; i+h-1 <= n; i++) {for(int j = 1; j <= m; j++) {addchar(ls(Hash[j][i][i+h-1]), j);}addchar(++shit, 0);}addchar(0, 0);sa.build_sa(shit+10);sa.build_height();for(int i = 1; i < sa.n; i++) if(pos[sa.sa[i]]) {ans += m - pos[sa.sa[i]] + 1 - sa.height[i];}}printf("Case #%d: ", ++kase);cout << ans << endl;} return 0;}
0 0
- HDU 4029 Distinct Sub-matrix(哈希+后缀数组)
- hdu 4029 Distinct Sub-matrix (后缀数组)
- HDU 4029 Distinct Sub-matrix(hash + 后缀数组)
- HDU 4029 Distinct Sub-matrix(后缀数组+hash)
- hdu 4029 Distinct Sub-matrix ( 后缀数组 + Hash )
- HDU 4029 Distinct Sub-matrix(11年上海热身 后缀数组)
- HDU 4029 Distinct Sub-matrix 后缀数组 + Hash 2011年上海网络赛I题
- 【后缀数组+字符串hash】 HDOJ 4029 Distinct Sub-matrix
- HDU 4029 Distinct Sub-matrix
- Distinct Sub-matrix HDOJ4416
- [HDU4029]Distinct Sub-matrix/[JZOJ4683]矩阵
- spoj 694 Distinct Substrings(后缀数组)
- SPOJ 694 Distinct Substrings(后缀数组)
- [SPOJ705]DISUBSTR - Distinct Substrings(后缀数组)
- SPOJ New Distinct Substrings(后缀数组)
- SPOJ DISUBSTR Distinct Substrings(后缀数组)
- Distinct Substrings后缀数组
- Distinct Substrings 后缀数组
- AFN框架实现简单的网络状态监测以及支持https安全证书
- Genymotion升完win10后无法打开
- VMWare安装CentOS图文教程
- <STL系列> 配置器
- android模拟器,Genymotion问题:Unable to start the virtual device.
- HDU 4029 Distinct Sub-matrix(哈希+后缀数组)
- 【Unity】 DoTween对UI进行DoFade操作存在问题及解决办法
- 顺序容器--字符串操作
- 我的第一个CSDN博客
- HDU 5514 【2015沈阳现场赛 F】 Frogs
- OC重点知识:代理
- maven自动部署web项目到tomcat8(向下兼容7)
- 解决adb server is out of date. killing... 报错
- 【Unity】使用Time.timeScale暂停游戏的时候的一些问题