题目描述
题目大意:无限大正方形网格里有n个黑色的顶点,所有其他顶点都是白色的(网格的顶点即坐标为整数的点,又称整点)。每秒钟,所有内部白点同时变黑,直到不存在内部白点为止。统计最后网格中的黑点个数。 内部白点的定义:一个白色的整点P(x,y)是内部白点当且仅当P在水平线的左边和右边各至少有一个黑点(即存在x1 < x < x2使得(x1,y)和(x2,y)都是黑点),且在竖直线的上边和下边各至少有一个黑点(即存在y1 < y < y2使得(x,y1)和(x,y2)都是黑点)。
题解
显然整个图只会变身一次→_→
所以答案即是将每一行的黑点连起来,每一列的黑点连起来搞出来一坨线段,求有多少个交点
注意线段长度为0(就是一个点)也计算在内
用扫描线的方法,将纵坐标离散,按横坐标排序,然后横向的线段的两个端点分别+1-1,每一次查询纵向的线段的范围内有多少个点就行了,注意对于每一个横坐标,先把能加进去的都加进去,统计完答案后再减去
其实这道题因为没有重复的纵坐标直接搞一个bit单点修改区间查询就行了,我比较sb写了线段树
代码
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
#define N 300005
int n,cnt,ans,LSH,lsh[N];
struct P{int x,y;}p[N];
struct OPT{int x,y,l,r,val;}opt[N];
int cover[N<<1],sum[N<<1];
int cmpx(P a,P b)
{
return a.x<b.x||(a.x==b.x&&a.y<b.y);
}
int cmpy(P a,P b)
{
return a.y<b.y||(a.y==b.y&&a.x<b.x);
}
int cmp(OPT a,OPT b)
{
return a.x<b.x||(a.x==b.x&&a.val>b.val);
}
void update(int now)
{
sum[now]=sum[now<<1]+sum[now<<1|1];
}
void change(int now,int l,int r,int x,int v)
{
int mid=(l+r)>>1;
if (l==r)
{
cover[now]+=v;
if (cover[now]) sum[now]=1;
else sum[now]=0;
return;
}
if (x<=mid) change(now<<1,l,mid,x,v);
else change(now<<1|1,mid+1,r,x,v);
update(now);
}
int query(int now,int l,int r,int lr,int rr)
{
int mid=(l+r)>>1,ans=0;
if (lr<=l&&r<=rr) return sum[now];
if (lr<=mid) ans+=query(now<<1,l,mid,lr,rr);
if (mid+1<=rr) ans+=query(now<<1|1,mid+1,r,lr,rr);
return ans;
}
int main()
{
scanf("%d",&n);
for (int i=1;i<=n;++i)
{
scanf("%d%d",&p[i].x,&p[i].y);
lsh[++LSH]=p[i].y;
}
sort(lsh+1,lsh+LSH+1);LSH=unique(lsh+1,lsh+LSH+1)-lsh-1;
for (int i=1;i<=n;++i)
p[i].y=lower_bound(lsh+1,lsh+LSH+1,p[i].y)-lsh;
sort(p+1,p+n+1,cmpy);
for (int i=1,j;i<=n;i=j)
{
j=i;
while (p[j].y==p[i].y)
++j;
opt[++cnt].x=p[i].x,opt[cnt].y=p[i].y,opt[cnt].val=1;
opt[++cnt].x=p[j-1].x,opt[cnt].y=p[i].y,opt[cnt].val=-1;
}
sort(p+1,p+n+1,cmpx);
for (int i=1,j;i<=n;i=j)
{
j=i;
while (p[j].x==p[i].x)
++j;
opt[++cnt].x=p[i].x,opt[cnt].l=p[i].y,opt[cnt].r=p[j-1].y;
}
sort(opt+1,opt+cnt+1,cmp);
for (int i=1;i<=cnt;++i)
{
if (opt[i].val)
change(1,1,LSH,opt[i].y,opt[i].val);
else
ans+=query(1,1,LSH,opt[i].l,opt[i].r);
}
printf("%d\n",ans);
}