Codeforces 1323B Count Subrectangles
题意:给你两个向量,相乘得到\(n*m\)的矩阵,求有多少个子矩阵,满足所有元素都为1,且数量为\(k\)
数据范围是4e4, 那么\(O(n^2)\)算法肯定不行, 分析知, 若列矩阵有0, 那么乘出的矩阵该列都为0, 那我们可以先将\(k\)分解, 然后前缀和优化列是否满足条件
#include<bits/stdc++.h>
using namespace std;
#define ms(x,y) memset(x, y, sizeof(x))
#define lowbit(x) ((x)&(-x))
typedef long long LL;
typedef pair<int,int> pii;
const int maxn = 4e4+7;
int a[maxn], b[maxn];
vector<pii> fac;
void get_fac(int n, int m, int k) {
for(int i = 1; i <= n; ++i) {
if((k%i) == 0 && (k/i) <= m)
fac.emplace_back(i, k/i);
}
}
void run_case() {
int n, m, k, t;
cin >> n >> m >> k;
for(int i = 1; i <= n; ++i) {
cin >> a[i];
}
for(int i = 1; i <= m; ++i) {
cin >> t;
b[i] = b[i-1] + t;
}
get_fac(n, m, k);
LL ans = 0;
for(auto v: fac) {
int row = v.first, col = v.second;
int tmp = 0;
for(int i = col; i <= m; ++i) {
if(b[i] - b[i-col] == col) tmp++;
}
int rownum = 0;
for(int i = 1; i <= n; ++i) {
if(a[i]) rownum++;
else {
rownum = 0;
continue;
}
if(rownum == row) {
ans += tmp;
rownum--;
}
}
}
cout << ans;
}
int main() {
ios::sync_with_stdio(false), cin.tie(0);
cout.flags(ios::fixed);cout.precision(2);
//int t; cin >> t;
//while(t--)
run_case();
cout.flush();
return 0;
}