【BZOJ1818】[CQOI2010]内部白点(树状数组,扫描线)

【BZOJ1818】[CQOI2010]内部白点(树状数组,扫描线)

题面

BZOJ

题解

不难发现(-1)就是在搞笑的。
那么对于每一行,我们显然可以处理出来最左和最右的点,那么等价于我们在横着的方向上得到了若干条线段,同理,在竖直方向上也得到了若干条线段,那么最终的答案就是这些线段的交点个数加上原先就有的白点个数,再减去交点上的黑点数目。
直接离散没有任何问题,那么直接扫描线计算即可。
代码有点丑。

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#define MAX 100100
inline int read()
{
	int x=0;bool t=false;char ch=getchar();
	while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
	if(ch=='-')t=true,ch=getchar();
	while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
	return t?-x:x;
}
struct Node{int x,y;}p[MAX];
bool operator<(Node a,Node b){if(a.y^b.y)return a.y<b.y;return a.x<b.x;}
bool cmp(Node a,Node b){if(a.x^b.x)return a.x<b.x;return a.y<b.y;}
struct Line{int x,y,v;}X[MAX<<1];
bool operator<(Line a,Line b){if(a.x^b.x)return a.x<b.x;return a.y<b.y;}
int Sx[MAX],tx,Sy[MAX],ty;
int n,ans,tot,c[MAX],v[MAX];
int lb(int x){return x&(-x);}
void add(int x,int w){while(x<=n)c[x]+=w,x+=lb(x);}
int getsum(int x){int s=0;while(x)s+=c[x],x-=lb(x);return s;}
int main()
{
	n=read();ans=n;
	for(int i=1;i<=n;++i)p[i].x=read(),p[i].y=read();
	for(int i=1;i<=n;++i)Sx[++tx]=p[i].x,Sy[++ty]=p[i].y;
	sort(&Sx[1],&Sx[tx+1]);tx=unique(&Sx[1],&Sx[tx+1])-Sx-1;
	sort(&Sy[1],&Sy[ty+1]);ty=unique(&Sy[1],&Sy[ty+1])-Sy-1;
	for(int i=1;i<=n;++i)p[i].x=lower_bound(&Sx[1],&Sx[tx+1],p[i].x)-Sx;
	for(int i=1;i<=n;++i)p[i].y=lower_bound(&Sy[1],&Sy[ty+1],p[i].y)-Sy;
	sort(&p[1],&p[n+1]);
	for(int i=1,j;i<=n;i=j+1)
	{
		j=i;while(j<n&&p[i].y==p[j+1].y)++j;
		X[++tot]=(Line){p[i].x,p[j].y,1};
		X[++tot]=(Line){p[j].x+1,p[j].y,-1};
	}
	sort(&p[1],&p[n+1],cmp);sort(&X[1],&X[tot+1]);
	for(int i=1,j,pos=1;i<=n;i=j+1)
	{
		j=i;while(j<n&&p[i].x==p[j+1].x)++j;
		int l=p[i].y,r=p[j].y,x=p[i].x;
		while(pos<=tot&&X[pos].x<=x)
		{
			int xx=X[pos].y;v[xx]+=X[pos].v;
			if(!v[xx])add(X[pos].y,-1);
			else if(v[xx]==1)add(X[pos].y,1);
			++pos;
		}
		ans+=getsum(r)-getsum(l-1);
		for(int k=i;k<=j;++k)if(v[p[k].y])ans-=1;
	}
	printf("%d
",ans);
	return 0;
}

原文地址:https://www.cnblogs.com/cjyyb/p/9804400.html