Time Limit: 10 Sec Memory Limit: 64 MB
Submit: 1394 Solved: 625
[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),即一个黑点的坐标。没有两个黑点的坐标相同,坐标的绝对值均不超过\(10 ^9\)。

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


扫描线板子题
易发现所有能变色的白点一定在第一秒就能变色,上下左右都有黑点。而且永不停止是不可能的。

把黑点离散化,按y排一下序,用vector在每一列的上端点存1,下端点存-1到每一行,顺便找出每一行的左端点和右端点用数组存下来

最后按行扫一遍,先加上端点再区间查询这一行的左右段点再减下端点即可


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<cstring>
using namespace std;

int i,m,n,j,k,zl[100001],zr[100001],x,y,l,r,ll[100001],rr[100001],c[100001],ans;

struct vv{  int x,y; } a[100001],b[100001];

vector <pair<int,int> > q[100001], p[100001];

bool cmp2(vv a,vv b) {if(a.y==b.y) return a.x<b.x; return a.y<b.y;}

void add(int now,int z) { for(int i=now;i<=y;i+=i & -i) c[i]+=z;}

int ask(int now)
{
    int ans=0;
    for(int i=now;i>0;i-=i & -i) ans+=c[i];
    return ans;
}

int main()
{
    scanf("%d",&n);
    for(i=1;i<=n;i++)
    {
        scanf("%d%d",&a[i].x,&a[i].y);
        zl[i]=a[i].x; zr[i]=a[i].y;
    }
    sort(zl+1,zl+1+n);  sort(zr+1,zr+1+n);
    x=unique(zl+1,zl+1+n)-zl-1; y=unique(zr+1,zr+1+n)-zr-1;

    for(i=1;i<=n;i++)
    {
        a[i].x=lower_bound(zl+1,zl+1+x,a[i].x)-zl, a[i].y=lower_bound(zr+1,zr+1+y,a[i].y)-zr;
        b[i].x=a[i].x; b[i].y=a[i].y;
    }
    sort(a+1,a+1+n,cmp2);
    l=0x3f3f3f3f; r=0;
    memset(ll,0x3f,sizeof(ll));
    for(i=1;i<=n;i++)
    {
        if(a[i].y!=a[i-1].y)
        {
            if(r) p[r].push_back(make_pair(a[i-1].y,-1)), q[l].push_back(make_pair(a[i-1].y,1));
            l=0x3f3f3f3f; r=0;
        }
        l=min(a[i].x,l); r=max(a[i].x,r);
        ll[a[i].x]=min(ll[a[i].x],a[i].y);
        rr[a[i].x]=max(rr[a[i].x],a[i].y);
    }
    if(r) p[r].push_back(make_pair(a[n].y,-1)), q[l].push_back(make_pair(a[n].y,1));

    for(i=1;i<=x;i++)
    {
        for(j=0;j<q[i].size();j++) add(q[i][j].first,q[i][j].second);
        if(rr[i])   ans+=ask(rr[i])-ask(ll[i]-1);
        for(j=0;j<p[i].size();j++) add(p[i][j].first,p[i][j].second);
    }
    printf("%d",ans);
}

1818: [Cqoi2010]内部白点的更多相关文章

  1. bzoj 1818 Cqoi2010 内部白点 扫描线

    [Cqoi2010]内部白点 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 1126  Solved: 530[Submit][Status][Disc ...

  2. 【BZOJ】1818: [Cqoi2010]内部白点(树状数组+离散+特殊的技巧)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1818 这一题一开始我就看错了,bzoj的那个绝对值109简直坑人,应该是10^9,我直接写了个暴力. ...

  3. bzoj 1818: [Cqoi2010]内部白点

    #include<cstdio> #include<iostream> #include<algorithm> using namespace std; struc ...

  4. BZOJ 1818: [Cqoi2010]内部白点 扫描线+树状数组

    问题转化为求每一个极长横线段与极长纵线段的交点个数. 这个东西用扫描线+树状数组维护一下就可以了. code: #include <cstdio> #include <algorit ...

  5. BZOJ 1818: [Cqoi2010]内部白点 (BIT + 扫描线)

    就是求多条线段的交点数,直接BIT+扫描线就行了. 注意不要算重最初存在的点. CODE #include<bits/stdc++.h> using namespace std; char ...

  6. BZOJ 1818: [Cqoi2010]内部白点(树状数组)

    传送门 解题思路 首先一定不可能有\(-1\)的情况,因为新产生的黑点不会造成任何贡献,它的各个方面都是不优的.那么只需要统计一遍答案,首先要将横坐标相同的两个点看成一条竖线,纵坐标相同的点看成一条横 ...

  7. Bzoj1818: [Cqoi2010]内部白点 && Tyvj P2637 内部白点 扫描线,树状数组,离散化

    1818: [Cqoi2010]内部白点 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 704  Solved: 344[Submit][Status] ...

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

    [BZOJ1818][CQOI2010]内部白点(树状数组,扫描线) 题面 BZOJ 题解 不难发现\(-1\)就是在搞笑的. 那么对于每一行,我们显然可以处理出来最左和最右的点,那么等价于我们在横着 ...

  9. 【BZOJ1818】[Cqoi2010]内部白点 扫描线+树状数组

    [BZOJ1818][Cqoi2010]内部白点 Description 无限大正方形网格里有n个黑色的顶点,所有其他顶点都是白色的(网格的顶点即坐标为整数的点,又称整点).每秒钟,所有内部白点同时变 ...

随机推荐

  1. MySql通用二进制版本在Linux(Ubuntu)下安装与开启服务

    安装mysql前可能需要其他软件的依赖,请先执行下面命令安装mysql的依赖软件 shell> apt-cache search libaio # search for info shell&g ...

  2. Java Singleton(单例模式) 实现详解

    什么是单例模式? Intend:Ensure a class only has one instance, and provide a global point of access to it. 目标 ...

  3. 响应式布局和BootStrap 全局CSS样式

    1.什么是响应式布局 响应式布局是Ethan Marcotte在2010年5月份提出的一个概念,这个概念是为解决移动互联网浏览而诞生的. 简而言之,就是一个网站能够兼容多个终端——而不是为每个终端做一 ...

  4. vs2017调试源代码

    最近刚入职 ,带我得导师发给我一堆项目,什么云端和医院端,各种wcf服务.window服务和一些公共类库来回调用.搞得是迷迷糊糊,晕头转向.反正是一脸大萌比... 不过经过几个日日夜夜得不停奋战,大致 ...

  5. HTML5 FormData实现文件上传实例

    表单提交,文件上传是一个常用又十分麻烦的功能,以前要上传文件通常都是借助插件或者flash来实现,噼里啪啦的加载一大堆东西.自从有了HTML5的FormData后,老板再也不用担心我的上传了. For ...

  6. JavaScript 面向对象的程序设计

    面向对象(Object-oriented,OO)的语言有一个标志,那就是它们都有类的概念.而通过类可以创建任意多个具有相同属性和方法的对象.前面提到过,ECMAScript中没有类的概念,因此它的对象 ...

  7. Android分享---调用系统自带的分享功能

    以前我们总想到友盟等平台分享功能的集成,集成这玩意还得下载对应的jar包.当然,用这些平台的分享并不是说什么好处都没有,至少人家的统计功能还是很实用的.不过有的时候我们是不需要多余功能的,只需要能分享 ...

  8. APP之红点提醒三个阶段

    下面这个页面就是我们进入APP后的主界面.客户选项的红点上数字就是显示我们没有查看的客户总数量.   当我们切换到客户这个fragment时,会显示贷款客户数量与保险客户数量.   当我们随便点击入一 ...

  9. redis介绍(7)高级用法

    redis的过期策略以及内存淘汰机制 分析:这个问题其实相当重要,到底redis有没用到家,这个问题就可以看出来.比如你redis只能存5G数据,可是你写了10G,那会删5G的数据.怎么删的,这个问题 ...

  10. 结对编程——四则运算器(UI第十组)

    博客目录: 一.问题描述                   二.设计思路                   三.UI开发过程                       四.对接过程       ...