Codeforces Round #626(Count Subrectangles)

题目:
You are given an array a of length n and array b of length m both consisting of only integers 0 and 1. Consider a matrix c of size n×m formed by following rule: ci,j=ai⋅bj (i.e. ai multiplied by bj). It’s easy to see that c consists of only zeroes and ones too.
How many subrectangles of size (area) k consisting only of ones are there in c?
A subrectangle is an intersection of a consecutive (subsequent) segment of rows and a consecutive (subsequent) segment of columns. I.e. consider four integers x1,x2,y1,y2 (1≤x1≤x2≤n, 1≤y1≤y2≤m) a subrectangle c[x1…x2][y1…y2] is an intersection of the rows x1,x1+1,x1+2,…,x2 and the columns y1,y1+1,y1+2,…,y2.
The size (area) of a subrectangle is the total number of cells in it.

Input
The first line contains three integers n, m and k (1≤n,m≤40000,1≤k≤n⋅m), length of array a, length of array b and required size of subrectangles.
The second line contains n integers a1,a2,…,an (0≤ai≤1), elements of a.
The third line contains m integers b1,b2,…,bm (0≤bi≤1), elements of b.

Output
Output single integer — the number of subrectangles of c with size (area) k consisting only of ones.

样例1:

输入:
3 3 2
1 0 1
1 1 1
输出:
4

样例2:

输入:
3 5 4
1 1 1
1 1 1 1 1
输出:
14

样例1解释:
在这里插入图片描述
题目大意: 有一个长度为n的矩阵a,还有一个长度为m的矩阵b,矩阵a和矩阵b中的元素只有0和1;现在矩阵c的构成满足下列条件:大小为n×m,且c[i][j] = a[i] * b[j];给定你一个整数k,求矩阵c中面积为k的矩形有多少个。

题解:
可以想到,如果在a数组里面有x个连续的1,然后b数组也有k/x个1的话,那么在c数组里面就可以形成一个面积为k的矩阵。所以找出k的所有因子,然后遍历,每次遍历加上a数组符合条件的个数乘以b数组符合条件的个数。

AC代码:

#include<iostream>
using namespace std;
#define ll long long
const int maxn = 1e5 + 5;
int a[maxn], b[maxn], c[maxn];
ll solve(int n, int m, int k){
    int i, t = 0;
    //找出k的所有因子
    for(i = 1; i * i <= k; i++){
        int x = k % i;
        if(x == 0){
            c[t++] = i;
            if(k / i == i)
                continue;
            c[t++] = k / i;
        }
    }
    ll x, y, res = 0;
    int num, j;
    for(i = 0; i < t; i++){
        x = 0, y = 0;
        num = 0;
        //找出a数组中符合的连续1
        for(j = 0; j < n; j++){
            num = (a[j] != 1 ? 0 : num + 1);
            if(c[i] == num)
                x++, num--;
        }
        num = 0;
        //同理:找出b数组中符合的连续1
        for(j = 0; j < m; j++){
            num = (b[j] != 1 ? 0 : num + 1);
            if(k / c[i] == num)
                y++, num--;
        }
        //求解
        res += x * y;
    }
    return res;
}
int main()
{

    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    std::cout.tie(0);
    int n, m, k; cin >> n >> m >> k;
    int i, j;
    for(i = 0; i < n; i++)
        cin >> a[i];
    for(j = 0; j < m; j++)
        cin >> b[j];
    ll ans = solve(n, m, k);
    cout << ans << endl;
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值