比赛链接:EC Final 2020
和 @cyx20110930 组的队,用他的号交的题。顺便帮助他橙名,好耶!(rk 25,我俩各写 2 道)
这道是 @cyx20110930 写的,顺便安利(copy)一下他的题解。
题目意思
有一个的棋盘,操作
次,每次删掉一个方格,问还剩几个长方形。
思路
正难则反,既然数有多少个比较困难,就直接每次查找少了几个长方形,十分简单。
代码
//暴力
//TEAM_NAME:CYX&LSY AK ICPC
//Problem B
//By CYX
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,m,down[505][505],up[505][505],grid[505][505];
int main()
{
cin>>n>>m;
//预处理
for(int i=1;i<=n;i++) {
for(int j=1;j<=m;j++){
up[i][j]=0;
down[i][j]=n+1;
}
}
int ans=n*(n+1)/2*m*(m+1)/2,q=n*m;
while(q--){
int x,y;
cin>>x>>y;
int u=0,d=n+1;
for(int j=y;j>=1;j--){//从1至y找u,d,看对每个格子能影响多大区域
if(grid[x][j]) break;
u=max(u,up[x][j]+1);
d=min(d,down[x][j]-1);
int a=u,b=d;
for(int k=y;k<=m;k++){//从y至n找u,d,看对每个格子能影响多大区域
if(grid[x][k]) break;
a=max(a,up[x][k]+1);
b=min(b,down[x][k]-1);
ans-=abs(x-a+1)*abs(b-x+1);
}
}
cout<<ans<<endl;
//更新
grid[x][y]=1;
for(int j=x;j<=n;j++)up[j][y]=max(up[j][y],x);
for(int j=x;j>=1;j--)down[j][y]=min(down[j][y],x);
}
return 0;
}