ACM-ICPC 2018 南京赛区网络预赛B--- The writing on the wall
逐个扫描每一个格子,设当前扫描的格子为(i, j),定义一种计数方式:以(i,j)为右下角的矩形个数,很明显,有高度为i,i-1,…,1总共i种矩形,同时有宽度为j,j-1,…,1总共j种矩形,共i*j个矩形(如果不排除含黑点的矩形)
当前求以(5,3)为右下角的矩形:宽度为1的矩形,只有5-4=1个(只有高度为1符合,从高度为2开始就包含黑块),而宽度为2的矩形,有5-5=0个,宽度为3也为0个;
扫描每一个点,遇到黑块就标记行;如果当前扫描到点(a,b),从宽度1、最右列开始扫描,对于当前列,取之前黑块所在行数最大值x,矩阵个数为a-x。
#include <bits/stdc++.h>
#define For(i,x,y) for(int i=(x);i<=(y);++i)
#define Fov(i,x,y) for(int i=(x);i>=(y);--i)
#define Fo(i,x,y) for(int i=(x);i<(y);++i)
#define midf(a,b) ((a)+(b)>>1)
#define Num1(_) (_)<<1
#define Num2(_) ((_)<<1)|1
#define ss(_) scanf("%s",_)
#define si(_) scanf("%d",&_)
#define sii(x,y) scanf("%d%d",&x,&y)
#define siii(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define mem(x,y) memset(x,y,sizeof(x))
using namespace std;
typedef long long ll;
typedef pair<int,int>P;
inline int read()
{
char ch=getchar(); int x=0, f=1;
while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar();}
while('0'<=ch&&ch<='9') { x=x*10+ch-'0'; ch=getchar();}
return x*f;
}
const int inf=0x3f3f3f3f;
const double pi=acos(-1.0);
const int n_max=1e5+10;
const int m_max=110;
int up[m_max];
bool vis[n_max][m_max];
int main()
{
int T,x,y,n,m,k,cas=0;
si(T);
while(T--)
{
siii(n,m,k);
For(i,1,m) up[i]=0;
For(i,1,n)
For(j,1,m) vis[i][j]=false;
For(i,1,k)
{
sii(x,y);
vis[x][y]=true;
}
ll ans=0;
For(i,1,n)
{
For(j,1,m)
{
if(vis[i][j]) up[j]=i;
int md=-inf;
Fov(k,j,1)
{
md=max(md,up[k]);
ans+=i-md;
}
}
}
printf("Case #%d: %lld\n",++cas,ans);
}
return 0;
}