hiho一下第234周《矩形计数》题目与解答

Posted paulzjt

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hiho一下第234周《矩形计数》题目与解答相关的知识,希望对你有一定的参考价值。

一、题目

题目1 : 矩形计数

时间限制:10000ms
单点时限:1000ms
内存限制:256MB

描述

如图所示,在由N行M列个单位正方形组成的矩形中,有K个单位正方形是黑色的,其余单位正方形是白色的。  

技术分享图片

你能统计出一共有多少个不同的子矩形是完全由白色单位正方形组成的吗?

输入

第一行三个整数:N, M和K。

之后K行每行包括两个整数R和C,代表一个黑色单位正方形的位置。

1 <= N,M <= 1000  

1 <= K <= 10  

1 <= R <= N  

1 <= C <= M

输出

输出一个整数表示满足条件的子矩形个数。

样例输入
3 3 1
2 3 
样例输出
24


二、思路

一开始没有思路,参考了官方分析之后豁然开朗。问题的关键点在于想到容斥原理和题解中的这句话:
我们知道只要确定矩形上边界、下边界、左边界和右边界的位置,就唯一确定了一个矩形。

三、实现

dfs实现容斥原理可以考虑用二进制来表示选取的集合状态。

技术分享图片
 1 //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@[email protected]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
 2  #include <iostream>
 3  #include <cstring>
 4  #include <cstdio>
 5  #include <string>
 6  #include <queue>
 7  #include <list>
 8  #include <map>
 9  #include <set>
10  #include <cmath>
11  #include <bitset>
12  #include <vector>
13  #include <sstream>
14  #include <cstdlib>
15  #include <algorithm>
16  using namespace std;
17  typedef long long  ll;
18  #define mem(A, X) memset(A, X, sizeof A)
19  #define foreach(e,x) for(__typeof(x.begin()) e=x.begin();e!=x.end();++e)
20  #define fori(i,l,u) for(ll (i)=(ll)(l);(i)<=(ll)(u);++(i))
21  #define ford(i,l,u) for(ll (i)=(ll)(l);(i)>=(ll)(u);--(i)) 
22 ll n,m,k;
23 const int maxsz=1005;
24 ll pr[maxsz],pc[maxsz];
25 ll sum;
26 ll cal(ll s){
27   if (s==0) return (n*n+n)*(m*m+m)/4;
28   ll lc=1000,rc=0,ur=0,dr=1000;
29   int cnt=0;
30 
31   //cout<<"----- s is : "<<s;
32   fori(i,1,k){
33    if(s&1){
34      lc=min(lc,pc[i]-1);
35      rc=max(rc,pc[i]);
36      ur=max(ur,pr[i]);
37      dr=min(dr,pr[i]-1);
38    }
39    s=s>>1;
40   }
41   //cout<<"  lc rc ur dr"<<lc<<" "<<rc<<" "<<ur<<" "<<dr<<endl;
42   ll sumx=(lc+1)*(m-rc+1);
43   //if(lx==rx) sumx=n*lx-lx*rx+n-rx+lx;
44   ll sumy=(dr+1)*(n-ur+1);
45   //if(lx==rx) sumy=n*lx-lx*rx+n-rx+lx;
46 
47   return sumx*sumy;
48 }
49 void dfs(ll cnt,ll s){
50   if(cnt<k){
51     int ns=(s<<1)+0;
52     dfs(cnt+1,ns);
53     ns=(s<<1)+1;
54     dfs(cnt+1,ns);
55   }else{
56     int cnt1=0;
57     int ts=s;
58     int cnt=k;
59     while(cnt--) {
60       if(ts&1) cnt1++;
61       ts=ts>>1;
62     }
63     int sig=-1;
64     if((cnt1%2)==0) sig=1;
65     ll temp=cal(s);
66     sum+=sig*temp;
67   }
68 
69 }
70 
71 
72  int main()
73  {
74   ios::sync_with_stdio(false);
75   //freopen("local.in","r",stdin);
76   //freopen("local.out","w",stdout);
77 
78   while(cin>>n>>m>>k){
79     fori(i,1,k) cin>>pr[i]>>pc[i];
80     sum=0;
81     dfs(0,0);
82     cout<<sum<<endl;
83   }
84 
85   return 0;
86  }
87 
88 //
89 //
90 //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@[email protected]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
View Code

 

 






以上是关于hiho一下第234周《矩形计数》题目与解答的主要内容,如果未能解决你的问题,请参考以下文章

hiho一下 第148周

hiho一下 第173周

hiho一下 第150周 -- Demo Day (DP)

hiho 1476 - 矩形计数 容斥

hiho一下 第174周

hiho一下 第172周