zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    Python 爬虫简介
    Python 线程池(小节)
    Python platform 模块
    Python term 模块
    python 统计使用技巧
    ArcGIS中的WKID(转)
    c#二维码资料
    How to remove live visual tree?
    新书预告 ArcGIS跨平台开发系列第一本
    visual studio 中删除多余的空白行
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/8142830.html
Copyright © 2011-2022 走看看