B1818 [Cqoi2010]内部白点 树状数组
这个题的想法很好想,就是进行排序之后直接检查每个点的上下左右是否有黑点就行.但是直接枚举显然不行,那怎么办呢?我们就用树状数组维护扫描线,把每排左右点看成一条线覆盖,然后从下往上扫,遇到下加一,遇到上减一并记录答案.这样用扫描线维护就行了.
题干:
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]内部白点 树状数组的更多相关文章
- BZOJ 1818: [Cqoi2010]内部白点(树状数组)
传送门 解题思路 首先一定不可能有\(-1\)的情况,因为新产生的黑点不会造成任何贡献,它的各个方面都是不优的.那么只需要统计一遍答案,首先要将横坐标相同的两个点看成一条竖线,纵坐标相同的点看成一条横 ...
- Bzoj1818: [Cqoi2010]内部白点 && Tyvj P2637 内部白点 扫描线,树状数组,离散化
1818: [Cqoi2010]内部白点 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 704 Solved: 344[Submit][Status] ...
- 【BZOJ1818】[CQOI2010]内部白点(树状数组,扫描线)
[BZOJ1818][CQOI2010]内部白点(树状数组,扫描线) 题面 BZOJ 题解 不难发现\(-1\)就是在搞笑的. 那么对于每一行,我们显然可以处理出来最左和最右的点,那么等价于我们在横着 ...
- 【BZOJ1818】[Cqoi2010]内部白点 扫描线+树状数组
[BZOJ1818][Cqoi2010]内部白点 Description 无限大正方形网格里有n个黑色的顶点,所有其他顶点都是白色的(网格的顶点即坐标为整数的点,又称整点).每秒钟,所有内部白点同时变 ...
- BZOJ_1818_[Cqoi2010]内部白点 _扫描线+树状数组
BZOJ_1818_[Cqoi2010]内部白点 _扫描线+树状数组 Description 无限大正方形网格里有n个黑色的顶点,所有其他顶点都是白色的(网格的顶点即坐标为整数的点,又称整点).每秒钟 ...
- 【BZOJ】1818: [Cqoi2010]内部白点(树状数组+离散+特殊的技巧)
http://www.lydsy.com/JudgeOnline/problem.php?id=1818 这一题一开始我就看错了,bzoj的那个绝对值109简直坑人,应该是10^9,我直接写了个暴力. ...
- BZOJ 1818: [Cqoi2010]内部白点 扫描线+树状数组
问题转化为求每一个极长横线段与极长纵线段的交点个数. 这个东西用扫描线+树状数组维护一下就可以了. code: #include <cstdio> #include <algorit ...
- bzoj1818 内部白点(好题) 离散化+树状数组
题目传送门 题意:给出很多黑点,当一个坐标上下左右都有黑点时,这个点也被染成黑色,问最后黑点的数量. 思路:首先,一个很显然的结论,不可能出现无限染色的情况.所以不会输出-1,当n为0或者1时,答案就 ...
- bzoj 1818 [CQOI 2010] 内部白点 - 扫描线 - 树状数组
题目传送门 快速的列车 慢速的列车 题目大意 一个无限大的方格图内有$n$个黑点.问有多少个位置上下左右至少有一个黑点或本来是黑点. 扫描线是显然的. 考虑一下横着的线段,取它两个端点,横坐标小的地方 ...
随机推荐
- 08Java Server Pages 语法
Java Server Pages 语法 基础语法 注释 <!-- -->可以在客户端通过源代码看到:<%-- --%>在客户端通过查看源代码看不到. <!--浏 ...
- react antD moment
import moment from 'moment' console.log(moment().add(1, 'days').format('YYYY-MM-DD')) //当前时间前一天 cons ...
- 网络编程 - join及守护线程
一.Join实例(join理解为等待)import threading,timedef run(n): time.sleep(3) print ("task",n)start = ...
- JAVA基础——IO流字节流
在Java中把不同的输入输出源(键盘.文件.网路连接)抽象表述为“流”. 1.输入流.输出流 .字节输入流通过FileInputStream和来操作 字节输出流通过FileOutputStream来操 ...
- 搜索--P1219 N皇后
题目描述 检查一个如下的6 x 6的跳棋棋盘,有六个棋子被放置在棋盘上,使得每行.每列有且只有一个,每条对角线(包括两条主对角线的所有平行线)上至多有一个棋子. 上面的布局可以用序列2 4 6 1 3 ...
- 每日命令:(5)rm
昨天学习了创建文件和目录的命令mkdir ,今天学习一下linux中删除文件和目录的命令: rm命令.rm是常用的命令,该命令的功能为删除一个目录中的一个或多个文件或目录,它也可以将某个目录及其下的所 ...
- Mac安装Qt出现错误Could not resolve SDK Path for 'macosx'
Qt 5.8 + Mac 10.14 qdevice.pri文件里没有网上说的那行应该改的代码,自己写上这句话也没有解决问题 最终解决方案: 在命令行输入:sudo xcode-select -s ...
- LINUX-文件的权限 - 使用 "+" 设置权限,使用 "-" 用于取消
ls -lh 显示权限 ls /tmp | pr -T5 -W$COLUMNS 将终端划分成5栏显示 chmod ugo+rwx directory1 设置目录的所有人(u).群组(g)以及其他人(o ...
- [luoguP2659] 美丽的序列(单调栈)
传送门 单调栈大水题 l[i] 表示 i 能扩展到的左边 r[i] 表示 i 能扩展到的右边 ——代码 #include <cstdio> #include <iostream> ...
- nyoj_116_士兵杀敌(二)_201404131107
士兵杀敌(二) 时间限制:1000 ms | 内存限制:65535 KB 难度:5 描述 南将军手下有N个士兵,分别编号1到N,这些士兵的杀敌数都是已知的. 小工是南将军手下的军师,南将军经常 ...