思路是枚举矩阵列数,然后将字符矩阵转换成字符串,通过字符数组求不同子串数目。最后,减去不成立的情况。使用特殊字符分割可能的组合。

 /* 4029 */
#include <iostream>
#include <sstream>
#include <string>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>
#include <deque>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <cstring>
#include <climits>
#include <cctype>
#include <cassert>
#include <functional>
#include <iterator>
#include <iomanip>
using namespace std;
//#pragma comment(linker,"/STACK:102400000,1024000") #define sti set<int>
#define stpii set<pair<int, int> >
#define mpii map<int,int>
#define vi vector<int>
#define pii pair<int,int>
#define vpii vector<pair<int,int> >
#define rep(i, a, n) for (int i=a;i<n;++i)
#define per(i, a, n) for (int i=n-1;i>=a;--i)
#define clr clear
#define pb push_back
#define mp make_pair
#define fir first
#define sec second
#define all(x) (x).begin(),(x).end()
#define SZ(x) ((int)(x).size())
#define lson l, mid, rt<<1
#define rson mid+1, r, rt<<1|1 const int maxr = ;
const int maxn = 2e5+;
const int base = ;
map<int,int> tb;
int a[maxn*];
int height[maxn], rrank[maxn], sa[maxn*];
int wa[maxn], wb[maxn], wc[maxn], wv[maxn];
char s[maxr][maxr];
int H[maxr][maxr];
int r, c; bool c0(int *r, int a, int b) {
return r[a]==r[b] && r[a+]==r[b+] && r[a+]==r[b+];
} bool c12(int k, int *r, int a, int b) {
if (k == )
return r[a]<r[b] || (r[a]==r[b] && c12(, r, a+, b+));
else
return r[a]<r[b] || (r[a]==r[b] && wv[a+]<wv[b+]);
} void sort(int *r, int *a, int *b, int n, int m) {
int i; for (i=; i<n; ++i) wv[i] = r[a[i]];
for (i=; i<m; ++i) wc[i] = ;
for (i=; i<n; ++i) wc[wv[i]]++;
for (i=; i<m; ++i) wc[i] += wc[i-];
for (i=n-; i>=; --i) b[--wc[wv[i]]] = a[i];
} #define F(x) ((x)/3 + ((x)%3==1 ? 0:tb))
#define G(x) ((x)<tb ? (x)*3+1 : ((x)-tb)*3+2)
void dc3(int *r, int *sa, int n, int m) {
int i, j, *rn=r+n, *san=sa+n, ta=, tb=(n+)/, tbc=, p; r[n] = r[n+] = ;
for (i=; i<n; ++i) if (i%!=) wa[tbc++] = i;
sort(r+, wa, wb, tbc, m);
sort(r+, wb, wa, tbc, m);
sort(r, wa, wb, tbc, m);
for (p=, rn[F(wb[])]=, i=; i<tbc; ++i)
rn[F(wb[i])] = c0(r, wb[i-], wb[i]) ? p- : p++;
if (p < tbc)
dc3(rn, san, tbc, p);
else
for (i=; i<tbc; ++i) san[rn[i]] = i;
for (i=; i<tbc; ++i)
if (san[i] < tb)
wb[ta++] = san[i] * ;
if (n% == )
wb[ta++] = n - ;
sort(r, wb, wa, ta, m);
for (i=; i<tbc; ++i) wv[wb[i]=G(san[i])] = i;
for (i=,j=,p=; i<ta && j<tbc; ++p)
sa[p] = c12(wb[j]%, r, wa[i], wb[j]) ? wa[i++] : wb[j++];
while (i < ta) sa[p++] = wa[i++];
while (j < tbc) sa[p++] = wb[j++];
} void calheight(int *r, int *sa, int n) {
int i, j, k = ; for (i=; i<=n; ++i) rrank[sa[i]] = i;
for (i=; i<n; height[rrank[i++]]=k)
for (k?k--:, j=sa[rrank[i]-]; r[j+k]==r[i+k]; ++k) ;
} void printSa(int n) {
for (int i=; i<=n; ++i)
printf("%d ", sa[i]);
putchar('\n');
} void printHeight(int n) {
for (int i=; i<=n; ++i)
printf("%d ", height[i]);
putchar('\n');
} void solve() {
__int64 ans = , tot, tmp;
int n = ; memset(H, , sizeof(H));
rep(w, , c+) {
tb.clr();
int cn = c - w + ;
int cnt = cn + ;
int sidx = ; rep(i, , r) {
rep(j, , cn) {
H[i][j] = H[i][j] * base + s[i][j+w-]-'A';
if (tb.find(H[i][j]) == tb.end())
tb[H[i][j]] = cnt++;
}
} n = ;
rep(j, , cn) {
rep(i, , r)
a[n++] = tb[H[i][j]];
a[n++] = sidx++;
}
a[n] = ; dc3(a, sa, n+, cnt+);
calheight(a, sa, n); tot = ;
rep(i, , n+)
tot += (n - sa[i] - height[i]); tmp = n;
rep(i, , cn) {
tmp -= r;
tot -= (r+) * tmp;
--tmp;
} ans += tot;
} printf("%I64d\n", ans);
} int main() {
ios::sync_with_stdio(false);
#ifndef ONLINE_JUDGE
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif int t; scanf("%d", &t);
rep(tt, , t+) {
scanf("%d %d", &r, &c);
rep(i, , r)
scanf("%s", s[i]);
printf("Case #%d: ", tt);
solve();
} #ifndef ONLINE_JUDGE
printf("time = %d.\n", (int)clock());
#endif return ;
}

数据生成器。

 from random import randint, shuffle
import shutil
import string def GenDataIn():
with open("data.in", "w") as fout:
t = 20
uc = list(string.uppercase)
fout.write("%d\n" % (t))
for tt in xrange(t):
n = randint(20, 50)
m = randint(20, 50)
fout.write("%d %d\n" % (n, m))
for i in xrange(n):
line = ""
for j in xrange(m):
idx = randint(0, 25)
line += uc[idx]
fout.write("%s\n" % (line)) def MovDataIn():
desFileName = "F:\eclipse_prj\workspace\hdoj\data.in"
shutil.copyfile("data.in", desFileName) if __name__ == "__main__":
GenDataIn()
MovDataIn()

【HDOJ】4029 Distinct Sub-matrix的更多相关文章

  1. 【线性代数】2-4:矩阵操作(Matrix Operations)

    title: [线性代数]2-4:矩阵操作(Matrix Operations) toc: true categories: Mathematic Linear Algebra date: 2017- ...

  2. 【HDOJ】2830 Matrix Swapping II

    简单DP. /* 2830 */ #include <iostream> #include <string> #include <map> #include < ...

  3. 【HDOJ】4729 An Easy Problem for Elfness

    其实是求树上的路径间的数据第K大的题目.果断主席树 + LCA.初始流量是这条路径上的最小值.若a<=b,显然直接为s->t建立pipe可以使流量最优:否则,对[0, 10**4]二分得到 ...

  4. 【Lintcode】118.Distinct Subsequences

    题目: Given a string S and a string T, count the number of distinct subsequences of T in S. A subseque ...

  5. 【leetcode】Search a 2D Matrix

    Search a 2D Matrix Write an efficient algorithm that searches for a value in an m x n matrix. This m ...

  6. 【leetcode】 Search a 2D Matrix (easy)

    Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the follo ...

  7. 【HDOJ】【3506】Monkey Party

    DP/四边形不等式 裸题环形石子合并…… 拆环为链即可 //HDOJ 3506 #include<cmath> #include<vector> #include<cst ...

  8. 【HDOJ】【3516】Tree Construction

    DP/四边形不等式 这题跟石子合并有点像…… dp[i][j]为将第 i 个点开始的 j 个点合并的最小代价. 易知有 dp[i][j]=min{dp[i][j] , dp[i][k-i+1]+dp[ ...

  9. 【HDOJ】【3480】Division

    DP/四边形不等式 要求将一个可重集S分成M个子集,求子集的极差的平方和最小是多少…… 首先我们先将这N个数排序,容易想到每个自己都对应着这个有序数组中的一段……而不会是互相穿插着= =因为交换一下明 ...

随机推荐

  1. double array trie 插入结点总结

    双数组Trie树索引的可操作性研究.pdf 提示:任一状态点的移动,会影响其Trie树中父节点的base值的选择以及兄弟结点位置的变动,而兄弟结点的移动又须变更相应的子节点的check值. 设待插入的 ...

  2. 用 .htaccess 实现网址规范化

    网址规范化在 SEO 中是一个比较重要的环节,同时存在不同的网址版本,不但可能造成内容重复,还不能正确的集中权重.目前大多数网站,绑定的域名都有带 www 和不带两个版本,甚至很多网站同时绑定多个域名 ...

  3. php下删除一篇文章生成的多个静态页面

    php自定义函数之删除一篇文章生成的多个静态页面,可能有多页的文章,都是需要考虑到的. 复制代码代码如下: //– 删除一篇文章生成的多个静态页面  //– 生成的文章名为 5.html 5_2.ht ...

  4. Pandas之容易让人混淆的行选择和列选择

    在刚学Pandas时,行选择和列选择非常容易混淆,在这里进行一下讨论和归纳 本文的数据来源:https://github.com/fivethirtyeight/data/tree/master/fa ...

  5. 以a为变量名,给出下列描述的定义

    a)一个整型数(An integer) b) 一个指向整型数的指针(A pointer to an integer) c) 一个指向指针的的指针,它指向的指针是指向一个整型数(A pointer to ...

  6. vim使用总结

    tar -xf vim.tar -C ~ vim /etc/vimrc vim /root/.vimrc set ts=4 设置tab有多少空格 set ai 自动对齐 set nu set mous ...

  7. crontab定时任务中文乱码问题

    手动执行都很正常的的脚本,添加到定时任务中日志文件全是乱码经过多方查证终于找到了原因! crontab启动的任务没有获取系统的环境变量,导致中文乱码解决办法:   在执行的脚步中添加编码方式或者添加对 ...

  8. c#面向对象机制的进一步理解

    今天看到一个面试题很有意思: namespace EventTest{ class Program { static void Main(string[] args) { A a = new C(); ...

  9. HTML元素大小和位置相对于谁的问题

    一.如果元素的position属性值为absolute,那么此时分为两种情况: 1. 父级(包括直接父级和间接父级)元素中没有定义position属性(即默认属性static),那么该元素会参照页面, ...

  10. 1038: [ZJOI2008]瞭望塔 - BZOJ

    Description 致力于建设全国示范和谐小村庄的H村村长dadzhi,决定在村中建立一个瞭望塔,以此加强村中的治安.我们将H村抽象为一维的轮廓.如下图所示 我们可以用一条山的上方轮廓折线(x1, ...