题目链接:点击查看

题目大意:给出一个数组 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(思维)相关推荐

  1. [codeforces 1327E] Count The Blocks 打表找规律+根据规律找公式+优化公式

    Educational Codeforces Round 84 (Rated for Div. 2)   比赛人数13522 [codeforces 1327E]  Count The Blocks  ...

  2. 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 ...

  3. CodeForces - 1000C Covered Points Count(差分+思维)

    题目链接:点击查看 题目大意:给出n个区间,现在要求输出覆盖次数为1,2,3....n-1,n的点分别有多少个 题目分析:一开始看到区间问题想用线段树去做,但想了想又可以直接用差分去做,不过因为数比较 ...

  4. 【Codeforces - 1000C】Covered Points Count(思维,离散化,差分)

    题干: You are given nn segments on a coordinate line; each endpoint of every segment has integer coord ...

  5. CodeForces - 1353E K-periodic Garland(思维+dp)

    题目链接:点击查看 题目大意:给出 n 个灯泡以及其初始状态(开或关),每次操作可以将任意一个灯泡的状态置反,问最少需要操作多少次,可以使得所有开着的灯泡之间相距 k 个单位 题目分析:因为需要满足所 ...

  6. CodeForces - 1593G Changing Brackets(思维)

    题目链接:点击查看 题目大意:给出一个长度为 nnn 的括号序列,其中包含了 {(,),[,]}\{(,),[,]\}{(,),[,]} 四种括号,现在可以进行两种操作: 将括号反转,代价为 000, ...

  7. CodeForces - 1567C Carrying Conundrum(思维/状压)

    题目链接:点击查看 题目大意:规定加法中使用隔项进位,问给定的 nnn 有多少种方案可以通过 "隔项进位加法" 得到 题目分析:隔项进位意味着奇偶位置的数字互不影响,所以将奇偶位置 ...

  8. CodeForces - 1535C Unstable String(思维)

    题目链接:点击查看 题目大意:规定一个字符串将问号都替换成 000 或 111 后满足 010101 交替的话,该字符串是合法的,现在给出一个长度为 nnn 的字符串,求合法子串的个数 题目分析:两种 ...

  9. CodeForces - 1321B Journey Planning(思维)

    题目链接:点击查看 题目大意:给出一个长度为 n 的数列,规定本题中的上升子序列必须满足两个条件: a[ j ] < a[ i ] a[ i ] - a[ j ] = i - j 问累加和最大的 ...

最新文章

  1. 6.MATLAB变量——矩阵操作一
  2. 2021-04-17 安装Ubuntu18.0.4 的深度学习训练服务器
  3. BPM助力先声药业优化流程管理
  4. 怎么改PHP_PHP实现RPC(简版)
  5. 【转】Windows编程之hdc和hwnd的区别
  6. 企业实战_18_MyCat_ZK集群安装部署
  7. xshell7官方个人免费版下载
  8. PHP连接MSSQL数据库案例,PHPWAMP多个PHP版本连接SQL Server数据库
  9. 计算机开机自检时,电脑开机启动时出现DHCP自检怎么办
  10. 微服务下蓝绿部署、红黑部署、AB测试、灰度发布、金丝雀发布、滚动发布的概念与区别...
  11. 移动硬盘使用mysql_移动硬盘如何正确使用才好?
  12. ThinkAdmin列目录/任意文件读取(CVE-2020-25540 )漏洞复现及环境搭建
  13. 积累的VC编程小技巧之打印相关
  14. 02.微软官方启动U盘装机教程
  15. 网站优化十大方法之关键字篇
  16. 7 HomePlug AV 中央协调器CCo
  17. Vue 3的设计过程(翻译自尤雨溪原文)
  18. 【EDA365电子论坛】硬件人经历南下、北上,回乡创业,后悔了吗?
  19. 城市如何缓解交通拥堵
  20. DRMsoft.cn未注册版 解决办法

热门文章

  1. 两线怎么接三线插座图_水温传感器怎么判断好坏
  2. Jasypt 加密-整合SpringBoot
  3. 常见的数据库管理系统排名(DBMS)
  4. 自定义负载均衡策略:
  5. 为什么需要Survivor区?只有Eden不行吗?
  6. MyBatis 实际使用案例-plugins
  7. MVC 顶层设计-HandlerMapping
  8. Collections集合工具类的方法_sort(List)
  9. SpringMVC拦截器之介绍和搭建环境
  10. Java语法糖之foreach