#6173. Samjia 和矩阵

题目链接  : 点这里

题目描述

给你一个只包含大写字母的矩阵,求有多少本质不同的子矩阵。

输入格式

第一行包含两个整数 nnn , mmm ,表示矩阵 nnn 行 mmm 列 。
接下来 nnn 行描述这个矩阵。

输出格式

只含一个整数,为本质不同的子矩阵个数。

样例

样例输入

3 3
ABA
BAA
AAA

样例输出

22

数据范围与提示

对于 10% 10\%10% 的数据,n,m≤10 n,m \leq 10n,m≤10;
对于 40% 40\%40% 的数据,n,m≤25 n,m \leq 25n,m≤25;
对于 70% 70\%70% 的数据,n,m≤60 n,m \leq 60n,m≤60;
对于 100% 100\%100% 的数据,n,m≤110 n,m \leq 110n,m≤110。

题解:

  

  

来自wannafly

#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define ls i<<1
#define rs ls | 1
#define pii pair<int,int>
#define MP make_pair
typedef long long LL;
typedef unsigned long long ULL;
const long long INF = 1e18+1LL;
const double pi = acos(-1.0);
const int N = 2e4+, M = 1e3+,inf = 2e9; int *ran,r[N],sa[N],height[N],wa[N],wb[N],wm[N];
bool cmp(int *r,int a,int b,int l) {
return r[a] == r[b] && r[a+l] == r[b+l];
}
void SA(int *r,int *sa,int n,int m) {
int *x=wa,*y=wb,*t;
for(int i=;i<m;++i)wm[i]=;
for(int i=;i<n;++i)wm[x[i]=r[i]]++;
for(int i=;i<m;++i)wm[i]+=wm[i-];
for(int i=n-;i>=;--i)sa[--wm[x[i]]]=i;
for(int i=,j=,p=;p<n;j=j*,m=p){
for(p=,i=n-j;i<n;++i)y[p++]=i;
for(i=;i<n;++i)if(sa[i]>=j)y[p++]=sa[i]-j;
for(i=;i<m;++i)wm[i]=;
for(i=;i<n;++i)wm[x[y[i]]]++;
for(i=;i<m;++i)wm[i]+=wm[i-];
for(i=n-;i>=;--i)sa[--wm[x[y[i]]]]=y[i];
for(t=x,x=y,y=t,i=p=,x[sa[]]=;i<n;++i) {
x[sa[i]]=cmp(y,sa[i],sa[i-],j)?p-:p++;
}
}
ran=x;
}
void Height(int *r,int *sa,int n) {
for(int i=,j=,k=;i<n;height[ran[i++]]=k)
for(k?--k:,j=sa[ran[i]-];r[i+k] == r[j+k];++k);
} const ULL mod = 10000019ULL;
int n,m;
ULL sqr[],has[][];
char a[][];
map<ULL,int >mp;
int main() {
sqr[] = ;
for(int i = ; i <= ; ++i) sqr[i] = sqr[i-] * mod;
scanf("%d%d",&n,&m);
for(int i = ; i <= n; ++i) {
scanf("%s",a[i]+);
has[i][] = ;
for(int j = ; j <= m; ++j) {
has[i][j] = has[i][j-] * mod + a[i][j] - 'A' + ;
}
}
LL ans = ;
for(int y = ; y <= m; ++y) {
int cnt = ,san = ;
mp.clear();
for(int j = ; j + y - <= m; ++j) {
for(int i = ; i <= n; ++i){
int l = j, rr = j + y - ;
ULL now = has[i][rr] - has[i][l-]*sqr[y];
if(mp[now] == ) mp[now] = san++;
r[cnt++] = mp[now];
}
r[cnt++] = san++;
}
r[cnt] = ; SA(r,sa,cnt+,san);
Height(r,sa,cnt);
//for(int i = 0; i <= cnt; ++i) cout<<sa[i]<<" "<<ran[i]<<" "<<height[i]<<endl;
// return 0;
ans += n*(n+)/*(m-y+); for(int i = ; i <= cnt; ++i) {
ans -= height[i];
}
}
printf("%lld\n",ans);
return ;
}

liberOJ #6173. Samjia 和矩阵 hash+后缀数组的更多相关文章

  1. loj6173 Samjia和矩阵(后缀数组/后缀自动机)

    题目: https://loj.ac/problem/6173 分析: 考虑枚举宽度w,然后把宽度压位集中,将它们哈希 (这是w=2的时候) 然后可以写一下string=“ac#bc” 然后就是求这个 ...

  2. [USACO07DEC]Best Cow Line G 字符串hash || 后缀数组

    [USACO07DEC]Best Cow Line G [USACO07DEC]Best Cow Line G 小声哔哔:字符串hash牛逼 题意 给出一个字符串,每次可以从字符串的首尾取出一个字符, ...

  3. Samjia 和矩阵[loj6173](Hash+后缀数组)

    传送门 本题要求本质不同的子矩阵,即位置不同也算相同(具体理解可以看样例自己yy). 我们先看自己会什么,我们会求一个字符串中不同的子串的个数.我们考虑把子矩阵变成一个字符串. 先枚举矩阵的宽度,记为 ...

  4. BZOJ 2119: 股市的预测 (Hash / 后缀数组 + st表)

    转博客大法好 自己画一画看一看,就会体会到这个设置关键点的强大之处了. CODE(sa) O(nlogn)→1436msO(nlogn)\to 1436msO(nlogn)→1436ms #inclu ...

  5. HDU-4622 Reincarnation 后缀数组 | Hash,维护和,扫描

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4622 题意:给一个字符串,询问某字串的不同字串的个数. 可以用后缀数组来解决,复杂度O(n).先求出倍 ...

  6. UVALive - 4513 Stammering Aliens ——(hash+二分 || 后缀数组加二分)

    题意:找一个出现了m次的最长子串,以及这时的最右的位置. hash的话代码还是比较好写的,,但是时间比SA多很多.. #include <stdio.h> #include <alg ...

  7. Uva12206 Stammering Aliens 后缀数组&&Hash

    Dr. Ellie Arroway has established contact with an extraterrestrial civilization. However, all effort ...

  8. Hash(LCP) || 后缀数组 LA 4513 Stammering Aliens

    题目传送门 题意:训练指南P225 分析:二分寻找长度,用hash值来比较长度为L的字串是否相等. #include <bits/stdc++.h> using namespace std ...

  9. acdream1116 Gao the string!(hash二分 or 后缀数组)

    问题套了一个斐波那契数,归根结底就是要求对于所有后缀s[i...n-1],所有前缀在其中出现的总次数.我一开始做的时候想了好久,后来看了别人的解法才恍然大悟.对于一个后缀来说 s[i...n-1]来说 ...

随机推荐

  1. 九度oj 题目1528:最长回文子串

    题目描述: 回文串就是一个正读和反读都一样的字符串,比如“level”或者“noon”等等就是回文串. 回文子串,顾名思义,即字符串中满足回文性质的子串. 给出一个只由小写英文字符a,b,c...x, ...

  2. EasyUI 加载Tree

    function LoadTree(result) { mainMenu = $('#mainMenu').tree({ url: "/ajax/GetTreeJson.ashx" ...

  3. 【Luogu】P3195玩具装箱(斜率优化DP)

    这题还是比较炫的 题目链接 我们设f[i]是已经装了前i个玩具,且第i个玩具是某箱子里装的最后一个东西(废话) 那我们很轻松可以想到一个转移方程 ;i<=n;++i) ;j<i;++j) ...

  4. [UOJ#223][BZOJ4654][Noi2016]国王饮水记

    [UOJ#223][BZOJ4654][Noi2016]国王饮水记 试题描述 跳蚤国有 n 个城市,伟大的跳蚤国王居住在跳蚤国首都中,即 1 号城市中.跳蚤国最大的问题就是饮水问题,由于首都中居住的跳 ...

  5. Office 中的各种小tips(更新中)

    1.Word 中打字输入会擦掉之后原有字符,出现“吃字”的情况? 要将“改写”切换为“插入”,最简单的方法就是点击键盘上小键盘旁边的“insert”键. 其实仔细观察的话,在word文档下方,会看到如 ...

  6. Linux(10):期中架构(2)--- NFS存储服务 & 实时同步

    1. 共享存储服务概念: # NFS是Network File System的缩写,中文意思是网络文件系统, # 它的主要功能是通过网络(一般是局域网)让不同的主机系统之间可以共享文件或目录. 2. ...

  7. Mountaineers

    Mountaineers 时间限制: 3 Sec  内存限制: 128 MB 题目描述 The Chilean Andes have become increasingly popular as a ...

  8. POJ3132 Sum of Different Primes

    Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 3473   Accepted: 2154 Description A pos ...

  9. net8:简易的文件磁盘管理操作一(包括文件以及文件夹的编辑创建删除移动拷贝重命名等)

    原文发布时间为:2008-08-07 -- 来源于本人的百度文章 [由搬家工具导入] using System;using System.Data;using System.Configuration ...

  10. C#.net的常用函数列表

    原文发布时间为:2008-08-03 -- 来源于本人的百度文章 [由搬家工具导入] 1、DateTime 数字型 System.DateTime currentTime=new System.Dat ...