zoukankan      html  css  js  c++  java
  • CF-div2-626-B. Count Subrectangles

    先想到,
    假如行有n个连续为1,列上有m个连续为1,则可以组成nm大小的矩阵。
    比如行1个连续,列2个连续。可以构成c[1][1]=1,c[1][2]=1,size=1
    2=2;

    然后就好办了。

    先想到一个暴力的思路,然后逐步优化。
    1.枚举x
    2.枚举y,当x*y == k,就是为了去构成大小为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
    */
    
  • 相关阅读:
    Java5 多线程实践
    ExtJS2.0实用简明教程 Border区域布局
    MySQL安装图解
    ExtJS2.0实用简明教程 组件的使用
    ExtJS2.0实用简明教程 ExtJS版的Hello
    Linux操作系统中如何安装Tomcat
    线程池的介绍及简单实现
    ExtJS2.0实用简明教程 获得ExtJS
    汽车常识全面介绍 动力系统
    MySQL 图形化管理工具介绍
  • 原文地址:https://www.cnblogs.com/fisherss/p/12450493.html
Copyright © 2011-2022 走看看