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;
}
posted @ 2020-03-08 22:12  GRedComeT  阅读(102)  评论(0编辑  收藏  举报