bzoj 1818 Cqoi2010 内部白点 扫描线
[Cqoi2010]内部白点
Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 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
0 2
2 0
-2 0
0 -2
Sample Output
5
数据范围
36%的数据满足:n < = 500
64%的数据满足:n < = 30000
100%的数据满足:n < = 100000
数据范围
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 }