CF-div2-626-B. Count Subrectangles

先想到一个暴力的思路,然后逐步优化。
1.枚举x
2.枚举y,当x*y == k
3.O(n^2)找出a数组长度为x且全1的个数,找出b数组长度为y且全1的个数,二者相乘,累加即可。

考虑优化的方案。
首先枚举y,可以变成计算y,y = k/x(当k%x==0)
然后找出a数组长度为x且全1的个数,可以使用前缀和优化成O(n)

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
const int maxn = 4e5+10;
int n,m,k;
ll a[maxn],b[maxn],col[maxn],row[maxn];
unordered_map<int,int> mp;
int main(){
    cin>>n>>m>>k;
    for(int i=1;i<=n;i++) {
        cin>>a[i];
        row[i] = row[i-1] + a[i];
    }
    for(int i=1;i<=m;i++) {
        cin>>b[i];
        col[i] = col[i-1] + b[i];
    }
    ll ans = 0;
    for(int i=1;i<=n;i++){
        if(k%i==0) mp[i] = k/i;
    }
    for(auto it:mp){
        int x = it.first;
        int y = it.second;
            ll cnt1 = 0,cnt2 = 0; //表示能构成行(列)为x(y)的个数 
            for(int i=1;i<=n-x+1;i++){
                if(row[i+x-1] - row[i-1] == x) //如果这段连续长度为x且这一段全为1 
                    cnt1 += 1;
            }
            for(int i=1;i<=m-y+1;i++){
                if(col[i+y-1] - col[i-1] == y) //如果这段连续长度为y且这一段全为1 
                    cnt2 += 1;
            }
            ans += cnt1*cnt2; //乘法原理 能组成cnt1*cnt2种方案构成size为k的矩形 
    }
    cout<<ans;
    return 0;
} 
/*
3 3 2
1 0 1
1 1 1
*/

猜你喜欢

转载自www.cnblogs.com/fisherss/p/12450493.html