bzoj 1818 Cqoi2010 内部白点 扫描线

[Cqoi2010]内部白点

Time Limit: 10 Sec  Memory Limit: 64 MB
Submit: 1126  Solved: 530
[Submit][Status][Discuss]

Description

无限大正方形网格里有n个黑色的顶点,所有其他顶点都是白色的(网格的顶点即坐标为整数的点,又称整点)。每秒钟,所有内部白点同时变黑,直到不存在内部白点为止。你的任务是统计最后网格中的黑点个数。 内部白点的定义:一个白色的整点P(x,y)是内部白点当且仅当P在水平线的左边和右边各至少有一个黑点(即存在x1 < x < x2使得(x1,y)和(x2,y)都是黑点),且在竖直线的上边和下边各至少有一个黑点(即存在y1 < y < y2使得(x,y1)和(x,y2)都是黑点)。

Input

输入第一行包含一个整数n,即初始黑点个数。以下n行每行包含两个整数(x,y),即一个黑点的坐标。没有两个黑点的坐标相同,坐标的绝对值均不超过109。

Output

输出仅一行,包含黑点的最终数目。如果变色过程永不终止,输出-1。

Sample Input

4
0 2
2 0
-2 0
0 -2

Sample Output

5

数据范围
36%的数据满足:n < = 500
64%的数据满足:n < = 30000
100%的数据满足:n < = 100000

发现第一秒变完后就没了,不可能为-1

然后就是扫描线求交点了。

  1 #include<cstring>
  2 #include<cmath>
  3 #include<algorithm>
  4 #include<iostream>
  5 #include<cstdio>
  6 
  7 #define N 100001
  8 #define M 1000001
  9 #define ll long long
 10 using namespace std;
 11 inline int read()
 12 {
 13     int x=0,f=1;char ch=getchar();
 14     while(ch>'9'||ch<'0'){if (ch=='-') f=-1;ch=getchar();}
 15     while(ch<='9'&&ch>='0'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
 16     return x*f;
 17 }
 18 
 19 int n,cnt,ans,hash[N],tr[N];
 20 struct point{int x,y;}a[N];
 21 struct seg{int k,x,y,r;}s[M];
 22 
 23 inline bool cmp1(point a,point b){if(a.x==b.x){return a.y<b.y;}return a.x<b.x;}
 24 inline bool cmp2(point a,point b){if(a.y==b.y){return a.x<b.x;}return a.y<b.y;}
 25 inline bool cmp3(seg a,seg b)
 26 {
 27     if(a.y==b.y)return a.k<b.k;
 28     return a.y<b.y;
 29 }
 30 int find(int x)
 31 {
 32     int l=1,r=n,mid;
 33     while(l<=r)
 34     {
 35         int mid=(l+r)>>1;
 36         if(hash[mid]<x)l=mid+1;
 37         else if(hash[mid]>x)r=mid-1;
 38         else return mid;
 39     }
 40 }
 41 void insert(int k,int l,int r,int t)//0横线,1竖线 
 42 {
 43     if(!k){s[++cnt].x=find(l);s[cnt].r=find(r);s[cnt].y=t;}
 44     else{
 45         s[++cnt].x=find(t);s[cnt].y=l;s[cnt].k=1;
 46         s[++cnt].x=find(t);s[cnt].y=r;s[cnt].k=-1; 
 47     }
 48 }
 49 void build()
 50 {
 51     sort(a+1,a+n+1,cmp1);
 52     for(int i=2;i<=n;i++)
 53         if(a[i].x==a[i-1].x)
 54             insert(1,a[i-1].y,a[i].y,a[i].x);
 55     sort(a+1,a+n+1,cmp2);
 56     for(int i=2;i<=n;i++)
 57         if(a[i].y==a[i-1].y)
 58             insert(0,a[i-1].x,a[i].x,a[i].y);
 59 }
 60 int lowbit(int x){return x&(-x);}
 61 void update(int x,int y)
 62 {
 63     while(x<=n)
 64     {
 65         tr[x]+=y;
 66         x+=lowbit(x);
 67     }
 68 }
 69 int ask(int x)
 70 {
 71     int s=0;
 72     while(x)
 73     {
 74         s+=tr[x];
 75         x-=lowbit(x);
 76     }
 77     return s;
 78 }
 79 void work()
 80 {
 81     for(int i=1;i<=cnt;i++)
 82     {
 83         if(!s[i].k)ans+=ask(s[i].r-1)-ask(s[i].x);
 84         else update(s[i].x,s[i].k);
 85     }
 86 }
 87 int main()
 88 {
 89     scanf("%d",&n);
 90     for(int i=1;i<=n;i++)
 91     {
 92         scanf("%d%d",&a[i].x,&a[i].y);
 93         hash[i]=a[i].x;
 94     }
 95     sort(hash+1,hash+n+1);
 96     build();
 97     sort(s+1,s+cnt+1,cmp3);
 98     work();
 99     printf("%d",ans+n);
100 }

 

posted @ 2017-12-29 09:36  Kaiser-  阅读(151)  评论(0编辑  收藏  举报