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

//枚举就好

#pragma warning(disable:4996)
#include"iostream"
#include"functional"
#include"algorithm"
#include"cstring"
#include"stack"
#include"cmath"
#include"queue"
#include"vector"
#include"map"
typedef long long int ll;
using namespace std;
pair<ll, ll> y[80000];
int cnt = 0, a, b, c;
map<ll, ll> ak, ac;
map<ll, ll>::iterator it, iy;
void get_c() {
	for (int i = 1; i <= sqrt(c); i++) {
		if (c % i == 0) {
			y[cnt].first = i;
			y[cnt++].second = c / i;
			if (i != c / i) {
                y[cnt].first = c / i;
			    y[cnt++].second = i;
			}
			
		}
	}
}
int main() {
	scanf("%lld%lld%lld", &a, &b, &c);
	get_c();
	ll l = 0, ans = 0, p = 0;
	for (int i = 0; i < a; i++) {
		scanf("%lld", &p);
		if (p) {
			l++;
		}
		else {
			ak[l]++;
			l = 0;
		}
	}
	if (l != 0) {
		ak[l]++;
		l = 0;
	}
	for (int i = 0; i < b; i++) {
		scanf("%lld", &p);
		if (p) {
			l++;
		}
		else {
			ac[l]++;
			l = 0;
		}
	}
	if (l != 0) {
		ac[l]++;
		l = 0;
	}
	for (int i = 0; i < cnt; i++) {
		ll hi = 0, li = 0;
		for ( it = ak.begin(); it != ak.end(); it++) {
			if ((*it).first >= y[i].first) {
				hi += ((*it).first - y[i].first + 1)* (*it).second;
			}
		}
		for (iy = ac.begin(); iy != ac.end(); iy++) {
			if ((*iy).first >= y[i].second) {
				li += ((*iy).first - y[i].second + 1) * (*iy).second;
			}
		}
		ans += li * hi;
	}
	cout << ans;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值