这个题的想法很好想,就是进行排序之后直接检查每个点的上下左右是否有黑点就行.但是直接枚举显然不行,那怎么办呢?我们就用树状数组维护扫描线,把每排左右点看成一条线覆盖,然后从下往上扫,遇到下加一,遇到上减一并记录答案.这样用扫描线维护就行了.

题干:

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
输出仅一行,包含黑点的最终数目。如果变色过程永不终止,输出-。
Sample Input -
-
Sample Output 数据范围
%的数据满足:n < =
%的数据满足:n < =
%的数据满足:n < =

代码:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<ctime>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std;
#define duke(i,a,n) for(int i = a;i <= n;i++)
#define lv(i,a,n) for(int i = a;i >= n;i--)
#define clean(a) memset(a,0,sizeof(a))
const int INF = << ;
typedef long long ll;
typedef double db;
template <class T>
void read(T &x)
{
char c;
bool op = ;
while(c = getchar(), c < '' || c > '')
if(c == '-') op = ;
x = c - '';
while(c = getchar(), c >= '' && c <= '')
x = x * + c - '';
if(op) x = -x;
}
template <class T>
void write(T x)
{
if(x < ) putchar('-'), x = -x;
if(x >= ) write(x / );
putchar('' + x % );
}
struct point
{
int x,y;
}a[];
struct seg
{
int k,x,y,r;
}s[];
int n;
int hsh[],cnt = ;
int tr[],ans = ;
bool cmp1(point a,point b)
{
if(a.x == b.x)
return a.y < b.y;
else
return a.x < b.x;
}
bool cmp2(point a,point b)
{
if(a.y == b.y)
return a.x < b.x;
else
return a.y < b.y;
}
bool cmp3(seg a,seg b)
{
if(a.y == b.y)
return a.k < b.k;
else
return a.y < b.y;
}
int find(int x)
{
int l = ,r = n,mid;
while(l <= r)
{
int mid = (l + r) >> ;
if(hsh[mid] < x)
l = mid + ;
else if(hsh[mid] > x)
r = mid - ;
else return mid;
}
}
void insert(int k,int l,int r,int t)
{
if(!k)
{
s[++cnt].x = find(l);
s[cnt].r = find(r);
s[cnt].y = t;
}
else
{
s[++cnt].x = find(t);
s[cnt].y = l;
s[cnt].k = ;
s[++cnt].x = find(t);
s[cnt].y = r;
s[cnt].k = -;
}
}
int lowbit(int x)
{
return x & -x;
}
void build()
{
sort(a + ,a + n + ,cmp1);
duke(i,,n)
{
if(a[i].x == a[i - ].x)
insert(,a[i - ].y,a[i].y,a[i].x);
}
sort(a + ,a + n + ,cmp2);
duke(i,,n)
{
if(a[i].y == a[i - ].y)
insert(,a[i - ].x,a[i].x,a[i].y);
}
}
void update(int x,int y)
{
while(x <= n)
{
tr[x] += y;
x += lowbit(x);
}
}
int ask(int x)
{
int s = ;
while(x)
{
s += tr[x];
x -= lowbit(x);
}
return s;
}
void work()
{
duke(i,,cnt)
{
if(!s[i].k)
ans += ask(s[i].r - ) - ask(s[i].x);
else
update(s[i].x,s[i].k);
}
}
int main()
{
read(n);
duke(i,,n)
{
read(a[i].x);
read(a[i].y);
hsh[i] = a[i].x;
}
sort(hsh + ,hsh + n + );
build();
sort(s + ,s + cnt + ,cmp3);
work();
printf("%d\n",ans + n);
return ;
}
/*
4
0 2
2 0
-2 0
0 -2
*/

B1818 [Cqoi2010]内部白点 树状数组的更多相关文章

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

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

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

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

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

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

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

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

  5. BZOJ_1818_[Cqoi2010]内部白点 _扫描线+树状数组

    BZOJ_1818_[Cqoi2010]内部白点 _扫描线+树状数组 Description 无限大正方形网格里有n个黑色的顶点,所有其他顶点都是白色的(网格的顶点即坐标为整数的点,又称整点).每秒钟 ...

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

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

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

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

  8. bzoj1818 内部白点(好题) 离散化+树状数组

    题目传送门 题意:给出很多黑点,当一个坐标上下左右都有黑点时,这个点也被染成黑色,问最后黑点的数量. 思路:首先,一个很显然的结论,不可能出现无限染色的情况.所以不会输出-1,当n为0或者1时,答案就 ...

  9. bzoj 1818 [CQOI 2010] 内部白点 - 扫描线 - 树状数组

    题目传送门 快速的列车 慢速的列车 题目大意 一个无限大的方格图内有$n$个黑点.问有多少个位置上下左右至少有一个黑点或本来是黑点. 扫描线是显然的. 考虑一下横着的线段,取它两个端点,横坐标小的地方 ...

随机推荐

  1. php redis使用 常用方法

    基本 $redis = new Redis();//创建对象 $redis->connect('127.0.0.1',6379);//建立连接 $redis->delete('test') ...

  2. gearman的安装与使用

    Gearman是一个分发任务的程序框架,它会对作业进行排队自动分配到一系列机器上.gearman跨语言跨平台,很方便的实现异步后台任务.php官方收录:http://php.net/manual/zh ...

  3. 关于vuex的理解

    刚开始学vue的时候,看到很多项目都有用vuex,抱着一种好奇的心态去看下vuex的官方文档,如下: Vuex官方文档 Vuex 是什么?Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式 ...

  4. Android studio升级后原有项目无法正常编译运行问题

    Android studio工具升级后Gradle版本问题 背景 升级AndroidStudio到最新版本后,原来可正常编译输出AndroidTest的项目无法正常编译通过. 原因 升级后的Andro ...

  5. 小程序button默认样式透彻理解

    微信小程序有一个默认样式,特别是有一个外边框,虽然看起来不别扭,但是自己每次设置border:0:都不生效,写成内联的样式也不生效,后来才知道里面的边框是伪元素的边框,这里的伪元素可以理解为用css动 ...

  6. 08css、JS

    08.css.JS-2018/07/18 1.css的属性 文字属性:font-size:大小,font-family字体类型,font-color:颜色 文本颜色:color:颜色,test-dec ...

  7. <MyBatis>入门三 sqlMapper文件

    增加 1.增删改在接口中的返回值 Integer.Long.Boolean.void 返回影响多少行 或 true | false 2.mapper 中 增删改没有返回值 (resultType或re ...

  8. CentOS7.x的DNS服务的基础配置

    一.bind服务器安装 bind:开源.稳定.应用广泛的DNS服务.bind的软件包名bind,服务名称named. 查看是否安装bind, 安装bind包: rpm -qa bind yum -y ...

  9. 有哪些可以节省chrome内存的扩展插件?

    不知道从什么时候开始,chrome浏览器就这样不知不觉的超过IE浏览器成为全球第一大浏览器.我们在赞赏chrome浏览器流畅的速度时,更多的是对其chrome插件功能的赞赏.但是我们也发现了一个致命的 ...

  10. Python学习笔记 (2)变量、常量和数据类型

    变量 顾名思义,变量就是一个会变的量,用一个变量名表示,指向内存中一片区域,而指向的区域存的是什么,这个变量就是什么数据类型,和C/C++挺不一样的.变量数据类型可以通过赋值变来变去(这就叫动态语言, ...