Codeforces Round #626 (Div. 2, based on Moscow Open Olympiad in Informatics)/CF1323 B. Count Subrectangles(枚举)

You are given an array aa of length nn and array bb of length mm both consisting of only integers 00 and 11 . Consider a matrix cc of size n×mn×m formed by following rule: ci,j=aibjci,j=ai⋅bj (i.e. aiai multiplied by bjbj ). It's easy to see that cc consists of only zeroes and ones too.

How many subrectangles of size (area) kk consisting only of ones are there in cc ?

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,y2x1,x2,y1,y2 (1x1x2n1≤x1≤x2≤n , 1y1y2m1≤y1≤y2≤m ) a subrectangle c[x1x2][y1y2]c[x1…x2][y1…y2] is an intersection of the rows x1,x1+1,x1+2,,x2x1,x1+1,x1+2,…,x2 and the columns y1,y1+1,y1+2,,y2y1,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 nn , mm and kk (1n,m40000,1knm1≤n,m≤40000,1≤k≤n⋅m ), length of array aa , length of array bb and required size of subrectangles.

The second line contains nn integers a1,a2,,ana1,a2,…,an (0ai10≤ai≤1 ), elements of aa .

The third line contains mm integers b1,b2,,bmb1,b2,…,bm (0bi10≤bi≤1 ), elements of bb .

Output

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

Examples
Input
Copy
3 3 2
1 0 1
1 1 1
Output
Copy
4
Input
Copy
3 5 4
1 1 1
1 1 1 1 1
Output
Copy14
题意是给一个只含0和1的矩阵,求里面所有全为1的且面积为k的子矩阵的个数。
首先要找出k的所有因子,根号n的复杂度就能解决。然后我一开始想的是分别枚举a数组和b数组里的连续含1区段,求每个区段里最多能包含多少个k的因子,把数目乘起来更新答案等等...这样的复杂度显然无法接受。看博客学习到更巧妙的解法,第一重循环枚举k的因子(全部),循环里嵌套两个并列的循环,一个遍历a数组,一个遍历b数组,分别找出有多少个长度为v[i]
的全1区间和长度为k/v[i]的含1区间。相乘即可。至于求法,用cnt为当前连续1的个数,遇到0就把cnt归零,遇到1++cnt,如果cnt等于v[i](或者k/v[i])的话更新个数同时cnt--(举个例子就能明白,1 1 1 1里长度为2的含1区间的下标为1 2 3,差1,因此要cnt--)。
记得开long long。
#include <bits/stdc++.h>
using namespace std;
int n,m,k;
int a[400005],b[400005];
int main()
{
    cin>>n>>m>>k;
    vector<int>v;//存放k的因子
    int i,j;
    for(i=1;i<=n;i++)scanf("%d",&a[i]);
    for(i=1;i<=m;i++)scanf("%d",&b[i]);
    for(i=1;i*i<=k;i++)
    {
        if(k%i==0)
        {
            v.push_back(i);
            if(i*i==k)continue;
            v.push_back(k/i);
        }
     } 
     long long ans=0;
    for(i=0;i<v.size();i++)
    {
        int x=0,y=0,cnt=0;//cnt为当前1的个数 
        for(j=1;j<=n;j++)
        {
            if(a[j]==1)cnt++;
            else cnt=0;
            if(cnt==v[i])//是==而非>= 
            {
                x++;
                cnt--;
            }
        }
        cnt=0;
        for(j=1;j<=m;j++)
        {
            if(b[j]==1)cnt++;
            else cnt=0;
            if(cnt==k/v[i])
            {
                y++;
                cnt--;
            }
        }
        ans+=x*y;
    }
    cout<<ans;
    return 0;
}
 
原文地址:https://www.cnblogs.com/lipoicyclic/p/12442902.html