题意:给你一个01矩阵,问此矩阵有多少个和恰好为k的子矩形。

思路:分治,对于当前矩形,用一条中线把矩形分成两半,分治之后计算跨过中线的矩形个数。更具体的来说(假设划了一条水平中线),我们枚举矩形左右边界,然后用指针维护一下到中线的连续和为k的边界。之后通过差分就可以计算出对应的左右边界的矩形的贡献数目。对于一个n * m的矩阵,计算贡献的时间复杂度是O(n * (m * k + n))的,带有n * n项,所以计算的时候需要用交替画水平线和竖直线,不然就超时了。总复杂度O(n * m * k * ( log(n) + log(m) ) );

代码:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 2510;
int sum[maxn][maxn];
char s[maxn][maxn];
int n, m, K;
long long ans;
int p1[10], p2[10];
int cal(int x1, int y1, int x2, int y2) {
return sum[x2][y2] - sum[x1 - 1][y2] - sum[x2][y1 - 1] + sum[x1 - 1][y1 - 1];
}
void div(int x1, int y1, int x2, int y2, bool flag) {
if(x1 > x2 || y1 > y2) return;
if(x1 == x2 && y1 == y2) {
ans += (cal(x1, y1, x2, y2) == K);
return;
}
if(flag) {
int mid = (x1 + x2) >> 1;
div(x1, y1, mid, y2, !flag);
div(mid + 1, y1, x2, y2, !flag);
for (int i = y1; i <= y2; i++) {
for (int k = 0; k <= K; k++) {
p1[k] = mid, p2[k] = mid + 1;
}
for (int j = y2; j >= i; j--) {
for (int k = 0; k <= K; k++) {
while(p1[k] >= x1 && cal(p1[k], i, mid, j) <= k) p1[k]--;
while(p2[k] <= x2 && cal(mid + 1, i, p2[k], j) <= k) p2[k]++;
}
for (int k = 1; k < K; k++) {
ans += (p1[k - 1] - p1[k]) * (p2[K - k] - p2[K - k - 1]);
}
if(K > 0) {
ans += (mid - p1[0]) * (p2[K] - p2[K - 1]);
ans += (p2[0] - mid - 1) * (p1[K - 1] - p1[K]);
} else if(K == 0) {
ans += (mid - p1[0]) * (p2[0] - mid - 1);
}
}
}
}
else {
int mid = (y1 + y2) >> 1;
div(x1, y1, x2, mid, !flag);
div(x1, mid + 1, x2, y2, !flag);
for (int i = x1; i <= x2; i++) {
for (int k = 0; k <= K; k++) {
p1[k] = mid, p2[k] = mid + 1;
}
for (int j = x2; j >= i; j--) {
for (int k = 0; k <= K; k++) {
while(p1[k] >= y1 && cal(i, p1[k], j, mid) <= k) p1[k]--;
while(p2[k] <= y2 && cal(i, mid + 1, j, p2[k]) <= k) p2[k]++;
}
for (int k = 1; k < K; k++) {
ans += (p1[k - 1] - p1[k]) * (p2[K - k] - p2[K - k - 1]);
}
if(K > 0) {
ans += (mid - p1[0]) * (p2[K] - p2[K - 1]);
ans += (p2[0] - mid - 1) * (p1[K - 1] - p1[K]);
} else if(K == 0) {
ans += (mid - p1[0]) * (p2[0] - mid - 1);
}
//printf("%d %d %d %d %d %d\n", x1, y1, x2, y2, 2, ans);
}
}
}
}
int main() {
//freopen("out.txt", "r", stdin);
scanf("%d%d%d", &n, &m, &K);
for (int i = 1; i <= n; i++) {
scanf("%s", s[i] + 1);
}
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++) {
sum[i][j] = sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1] + (s[i][j] == '1');
}
div(1, 1, n, m, 0);
printf("%lld\n", ans);
}

  

Codeforces 364E 分治的更多相关文章

  1. Pudding Monsters CodeForces - 526F (分治, 双指针)

    大意: n*n棋盘, n个点有怪兽, 求有多少边长为k的正方形内恰好有k只怪兽, 输出k=1,...,n时的答案和. 等价于给定n排列, 对于任意一个长为$k$的区间, 若最大值最小值的差恰好为k, ...

  2. A Story of One Country (Hard) CodeForces - 1181E2 (分治)

    大意: 给定$n$个平面上互不相交的矩形. 若一个矩形区域只包含一个矩形或者它可以水平或垂直切成两块好的区域, 那么这个矩形区域是好的. 求判断整个平面区域是否是好的. 分治判断, 可以用链表实现删除 ...

  3. Codeforces 1039D You Are Given a Tree [根号分治,整体二分,贪心]

    洛谷 Codeforces 根号分治真是妙啊. 思路 考虑对于单独的一个\(k\)如何计算答案. 与"赛道修建"非常相似,但那题要求边,这题要求点,所以更加简单. 在每一个点贪心地 ...

  4. Codeforces Round #190 (Div. 2) E. Ciel the Commander 点分治

    E. Ciel the Commander Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.codeforces.com/contest ...

  5. CodeForces 553E Kyoya and Train 动态规划 多项式 FFT 分治

    原文链接http://www.cnblogs.com/zhouzhendong/p/8847145.html 题目传送门 - CodeForces 553E 题意 一个有$n$个节点$m$条边的有向图 ...

  6. CodeForces 958F3 Lightsabers (hard) 启发式合并/分治 多项式 FFT

    原文链接http://www.cnblogs.com/zhouzhendong/p/8835443.html 题目传送门 - CodeForces 958F3 题意 有$n$个球,球有$m$种颜色,分 ...

  7. codeforces 161D Distance in Tree 树上点分治

    链接:https://codeforces.com/contest/161/problem/D 题意:给一个树,求距离恰好为$k$的点对是多少 题解:对于一个树,距离为$k$的点对要么经过根节点,要么 ...

  8. Codeforces 833D Red-Black Cobweb [点分治]

    洛谷 Codeforces 思路 看到树上路径的统计,容易想到点分治. 虽然只有一个限制,但这个限制比较麻烦,我们把它拆成两个. 设黑边有\(a\)条,白边有\(b\)条,那么有 \[ 2a\geq ...

  9. Codeforces 1093E Intersection of Permutations [CDQ分治]

    洛谷 Codeforces 思路 一开始想到莫队+bitset,发现要T. 再想到分块+bitset,脑子一抽竟然直接开始写了,当然也T了. 最后发现这就是个裸的CDQ分治-- 发现\(a\)不变,可 ...

随机推荐

  1. Sass--传一个不带值的参数

    Sass 的混合宏有一个强大的功能,可以传参,那么在 Sass 中传参主要有以下几种情形: A) 传一个不带值的参数 在混合宏中,可以传一个不带任何值的参数,比如: @mixin border-rad ...

  2. word里输入英文字母间距变宽,字体改变,怎么回事?

    word里输入英文字母间距变宽,字体改变,怎么回事? 你有没有遇到下面这种情况,在word里输入英文,变的很奇怪,就像下面图中那样: 是不是很蛋疼?看起来很别扭. 那是因为输入法是全角状态 我们只要把 ...

  3. Autoit3域用户的登陆统计

    #include <ACN_NET.au3> If @OSArch="X86" Then $fileURL=@CommonFilesDir & "\S ...

  4. leetcode-167周赛-1293-网格中的最短路径

    题目描述: 自己的提交:广度优先 O(mn*min(k,m+n)) class Solution: def shortestPath(self, grid, k: int) -> int: vi ...

  5. webpack CSS处理loader

    loader概念: 首先来介绍一下loader,之前我们用webpack来处理我们写的js代码,并且webpack会自动处理js之间相关的依赖.但是,在开发中我们不仅仅有基本的js代码处理,我们也需要 ...

  6. 阿里云李刚:下一代低延时的直播CDN

    在上周落幕帷幕的多媒体领域技术盛会——LiveVideoStackCon音视频技术大会上,阿里云的高级技术专家李刚进行了<下一代低延时的直播CDN>技术分享.主讲人李刚,多年关注在CDN这 ...

  7. Android逆向之旅---Android应用的汉化功能(修改SO中的字符串内容)

    一.前言 今天我们继续来讲述逆向的知识,今天我们来讲什么呢?我们在前一篇文章中介绍了关于SO文件的格式,今天我们继续这个话题来看看如何修改SO文件中的内容,看一下我们研究的主题: 需求:想汉化一个Ap ...

  8. paper 160:python 知识点概要 更新ing

    1.python json  http://www.runoob.com/python/python-json.html Python的json模块提供了一种很简单的方式来编码和解码JSON数据. 其 ...

  9. Scrapy模拟登陆豆瓣抓取数据

    scrapy  startproject douban 其中douban是我们的项目名称 2创建爬虫文件 进入到douban 然后创建爬虫文件 scrapy genspider dou douban. ...

  10. python练习题自己实现一个字符串的find函数

    # 第五题:自己实现一个字符串的find函数 # 1.在一个字符串中查找另一个字符串 # 2.找到了返回第一次出现的位置 # 3.没找到返回-1 # 4.参数s1为源字符串,参数s2为要查找的字符串 ...