2020.9.11BNUZ练习

2020.9.11BNUZ练习


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

Examples
Input
3 3 2
1 0 1
1 1 1

Output
4

Input
3 5 4
1 1 1
1 1 1 1 1
Output
14

题意
c[i,j] = a[i]*b[j],计算c矩阵中面积为k的矩形。

题解

理解a代表的是行,b代表的是列,用若ka表示行长,用kb表示列长,则面积k=ka*kb;所以核心是求a和b中连续为1的子串。
⚠️:在计算长度为dp[i]的子串数量时,我们还要加上比它大的子串数量。(比如说:dp[2]显示有n个长度为2的子串,有m个长度为3的子串,但事实上m个长度为3的子串必定包含了m个长度为2的子串,所以依此类推,比2长的都要加到长度为2里面)

#include
#include
#include
using namespace std;
typedef long long ll;
void getsub(int *a,int *dp_a,int n){
     //求连续子串
    for(int i = 1;i <= n;i++){
     
        if(a[i] == 1)
            dp_a[i] = dp_a[i-1]+1;
        else
            dp_a[i] = 0;
    }
}
int main(){
     
    int n,m;
    ll k;
    scanf("%d %d %lld",&n,&m,&k);
    int a[n+5],b[m+5];
    int dp_a[n+5],dp_b[m+5];
    ll sum = 0;
    for(int i = 1;i <= n;i++) scanf("%d",&a[i]);
    for(int i = 1;i <= m;i++) scanf("%d",&b[i]);
    memset(dp_a, 0, sizeof(dp_a));
    memset(dp_b, 0, sizeof(dp_b));
    getsub(a, dp_a, n);
    getsub(b, dp_b, m);
    for (int i = 1; i <= n; i++) {
     
        int con_a = 0,con_b = 0;
        if(!(k % i)){
     
            for(int j = 1;j <= n;j++){
     
                if(dp_a[j] >= i)
                    con_a++;
            }
            for (int j = 1; j <= m; j++) {
     
                if(dp_b[j] >= k/i)
                    con_b++;
            }
            sum += con_b*con_a;
        }
    }
    printf("%lld\n",sum);
}

你可能感兴趣的:(2020.9.11BNUZ练习)