CodeForces - 1323B Count Subrectangles(思维)
题目链接:点击查看
题目大意:给出一个数组 a 和数组 b 只由 0 和 1 构成,构造出矩阵 maze[ x ][ y ] = a[ x ] * b[ y ],显然maze矩阵同样只由 0 和 1 构成,现在要求面积为 k 的子矩阵中,有多少个全部为 1
题目分析:再次感觉难度大于 C 题的一道 B 题。。考察的方面很综合,不知道如何分类,就暂且分为思维吧,首先排除n*m*n*m的暴力,接下来一步一步考虑,因为面积为 k 的子矩阵,换一种说法,假设子矩阵的大小为 x * y ,则必须满足 x * y == k 的子矩阵才可能满足条件,所以不难想到要对面积 k 进行因数分解,sqrt( k )的时间复杂度预处理出 k 的所有因数作为子矩阵的长和宽,对于每一对可行的长和宽 ( x , y ) 来说,都需要计算其贡献,接下来说的内容可能有点抽象,后面我会举例子说明的。现在的问题转换为了,给出指定大小的子矩阵 ( x , y ) ,如何计算出其出现次数,通过观察样例给出的矩阵可以发现,假设某个子矩阵的左上角端点为( x1 , y1 ),右下角端点为( x2 , y2 ),若该子矩阵想要全部为 1 的话,那么数组 a[ x1 ] ~ a[ x2 ] 以及 b[ y1 ] ~ b[ y2 ] 的这两段连续区间内必须全部为 1 才行,这样就可以将数组 a 以及数组 b 转换为连续的 1 储存了,比如数组 a 原本为 1011011101 ,那么转换后就变为了 1,2,3,1 了,我们记为 aa 数组和 bb 数组,这样转换后有什么用呢?剩下的其实就可以排列组合计算答案了,还是以大小为( x , y )的子矩阵为例,我们遍历一遍 aa 数组,可以对大小为 x * y 的子矩阵做出贡献,那么必须满足连续的行数大于等于 x 才行,通过平移可以知道,贡献就是 aa[ i ] - x + 1 了,遍历一遍数组aa后,可以计算出有多少种行可以做出贡献,同理遍历一遍 bb 数组后计算出有多少列可以做出贡献,相乘就是总贡献了
下面举一个例子,就拿样例为例,a 数组为 1 0 1,转换为 aa 数组也就变成了 1,1
b 数组为 1 1 1,转换为 bb 数组也就变成了 3
以大小为 ( 1 , 2 ) 的子矩阵为例,我们需要在 aa 数组中找到有多少个连续的行满足 aa[ i ] >= 1,显然有两个
接下来需要在 bb 数组中找到有多少个连续的列,满足 bb[ i ] >= 2 ,因为 bb 数组只有一个元素,且其值为 3 ,那么对列的贡献也就是 2 了,因为可以这样选:(选橙色的列)
1 1 1
也可以这样选:
1 1 1
综上,对于子矩阵 ( 1 , 2 ) 的贡献为 2 * 2 = 4
总时间复杂度为 sqrt( n * m )*( n + m ),我用了unordered_map稍加优化,而且sqrt(n*m)应该也不会拉满,所以评测机给出的反馈是十分不错的
代码:
#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<unordered_map>
using namespace std;typedef long long LL;typedef unsigned long long ull;const int inf=0x3f3f3f3f;const int N=4e4+100;int a[N],b[N];vector<pair<int,int>>node;void init(int k)
{for(int i=1;i*i<=k;i++){if(k%i==0){node.push_back(make_pair(i,k/i));if(i!=k/i)node.push_back(make_pair(k/i,i));}}
}unordered_map<int,int>A,B;void solve(int a[],int n,unordered_map<int,int>& mp)
{int pos=1,cnt=0;while(pos<=n){while(a[pos]){pos++;cnt++;}if(cnt){mp[cnt]++;cnt=0;}pos++;}
}int main()
{
#ifndef ONLINE_JUDGE
// freopen("input.txt","r",stdin);
// freopen("output.txt","w",stdout);
#endif
// ios::sync_with_stdio(false);int n,m,k;scanf("%d%d%d",&n,&m,&k);init(k);for(int i=1;i<=n;i++)scanf("%d",a+i);for(int i=1;i<=m;i++)scanf("%d",b+i);solve(a,n,A);//预处理出aa数组和bb数组,存放在unordered_map中solve(b,m,B);LL ans=0;for(int k=0;k<node.size();k++)//遍历每对因子{int x=node[k].first,y=node[k].second;LL xx=0,yy=0;for(auto it:A)//行贡献if(it.first>=x)xx+=it.second*(it.first-x+1);for(auto it:B)//列贡献if(it.first>=y)yy+=it.second*(it.first-y+1);ans+=xx*yy;//累加贡献}printf("%lld\n",ans);return 0;
}
CodeForces - 1323B Count Subrectangles(思维)相关推荐
- [codeforces 1327E] Count The Blocks 打表找规律+根据规律找公式+优化公式
Educational Codeforces Round 84 (Rated for Div. 2) 比赛人数13522 [codeforces 1327E] Count The Blocks ...
- Count Subrectangles CodeForces - 1323B(思维)
You are given an array a of length n and array b of length m both consisting of only integers 0 and ...
- CodeForces - 1000C Covered Points Count(差分+思维)
题目链接:点击查看 题目大意:给出n个区间,现在要求输出覆盖次数为1,2,3....n-1,n的点分别有多少个 题目分析:一开始看到区间问题想用线段树去做,但想了想又可以直接用差分去做,不过因为数比较 ...
- 【Codeforces - 1000C】Covered Points Count(思维,离散化,差分)
题干: You are given nn segments on a coordinate line; each endpoint of every segment has integer coord ...
- CodeForces - 1353E K-periodic Garland(思维+dp)
题目链接:点击查看 题目大意:给出 n 个灯泡以及其初始状态(开或关),每次操作可以将任意一个灯泡的状态置反,问最少需要操作多少次,可以使得所有开着的灯泡之间相距 k 个单位 题目分析:因为需要满足所 ...
- CodeForces - 1593G Changing Brackets(思维)
题目链接:点击查看 题目大意:给出一个长度为 nnn 的括号序列,其中包含了 {(,),[,]}\{(,),[,]\}{(,),[,]} 四种括号,现在可以进行两种操作: 将括号反转,代价为 000, ...
- CodeForces - 1567C Carrying Conundrum(思维/状压)
题目链接:点击查看 题目大意:规定加法中使用隔项进位,问给定的 nnn 有多少种方案可以通过 "隔项进位加法" 得到 题目分析:隔项进位意味着奇偶位置的数字互不影响,所以将奇偶位置 ...
- CodeForces - 1535C Unstable String(思维)
题目链接:点击查看 题目大意:规定一个字符串将问号都替换成 000 或 111 后满足 010101 交替的话,该字符串是合法的,现在给出一个长度为 nnn 的字符串,求合法子串的个数 题目分析:两种 ...
- CodeForces - 1321B Journey Planning(思维)
题目链接:点击查看 题目大意:给出一个长度为 n 的数列,规定本题中的上升子序列必须满足两个条件: a[ j ] < a[ i ] a[ i ] - a[ j ] = i - j 问累加和最大的 ...
最新文章
- 6.MATLAB变量——矩阵操作一
- 2021-04-17 安装Ubuntu18.0.4 的深度学习训练服务器
- BPM助力先声药业优化流程管理
- 怎么改PHP_PHP实现RPC(简版)
- 【转】Windows编程之hdc和hwnd的区别
- 企业实战_18_MyCat_ZK集群安装部署
- xshell7官方个人免费版下载
- PHP连接MSSQL数据库案例,PHPWAMP多个PHP版本连接SQL Server数据库
- 计算机开机自检时,电脑开机启动时出现DHCP自检怎么办
- 微服务下蓝绿部署、红黑部署、AB测试、灰度发布、金丝雀发布、滚动发布的概念与区别...
- 移动硬盘使用mysql_移动硬盘如何正确使用才好?
- ThinkAdmin列目录/任意文件读取(CVE-2020-25540 )漏洞复现及环境搭建
- 积累的VC编程小技巧之打印相关
- 02.微软官方启动U盘装机教程
- 网站优化十大方法之关键字篇
- 7 HomePlug AV 中央协调器CCo
- Vue 3的设计过程(翻译自尤雨溪原文)
- 【EDA365电子论坛】硬件人经历南下、北上,回乡创业,后悔了吗?
- 城市如何缓解交通拥堵
- DRMsoft.cn未注册版 解决办法