BZOJ 1818 [Cqoi2010]内部白点
来源:互联网 发布:电视直播软件看不了 编辑:程序博客网 时间:2024/04/28 01:31
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
这道题是好题啊2333
首先我们可以发现题目中说输出-1是为了故意迷惑你的,其实只有第一秒,永远不会输出-1,不会无限添加黑点,连第二秒都没有
然后我们可以离散化x坐标,然后把竖着的一条线段(x坐标相同),认为是一个两个事件,我们从下往上扫的时候,把下面当做加入,上面当成取出,也就是说下面树状数组上+1,上面-1,而对于横着的一条线段,我们认为是一个询问事件,询问当前这个区间内有多少个点,让其有交点,累加答案的时候边界,树状数组有些时候会把边界搞错
#include<iostream>#include<cstdio>#include<algorithm>using namespace std;int n, tail, ans, C[100001];struct LSH{ int x, id; } lsh[100001];struct Poi{ int x, y; } p[100001];struct Seg{int k, l, r, y;} seg[1000001];bool cmp0( const LSH &a, const LSH &b ) { return a.x < b.x; }bool cmp1( const Poi &a, const Poi &b ) { if( a.x != b.x ) return a.x < b.x; else return a.y < b.y;}bool cmp2( const Poi &a, const Poi &b ) { if( a.y != b.y ) return a.y < b.y; else return a.x < b.x;}bool cmp3( const Seg &a, const Seg &b ) { if( a.y != b.y ) return a.y < b.y; else return a.k < b.k; }void add_line( int k, int l, int r, int t ) { if( !k ) { seg[++tail].l = l; seg[tail].y = t; seg[tail].r = r; } //线段 else {//点 seg[++tail].l = t; seg[tail].y = l; seg[tail].k = 1; seg[++tail].l = t; seg[tail].y = r; seg[tail].k = -1; }}void build( ) { sort( p + 1, p + n + 1, cmp1 ); for( register int i = 2; i <= n; i++ ) if( p[i].x == p[ i - 1 ].x ) add_line( 1, p[ i - 1 ].y, p[i].y, p[i].x ); sort( p + 1, p + n + 1, cmp2 ); for( register int i = 2; i <= n; i++ ) if( p[i].y == p[ i - 1 ].y ) add_line( 0, p[ i - 1 ].x, p[i].x, p[i].y );}void modify( int x, int y ) { for( ; x <= n ; x += x & -x ) C[x] += y; }int query( int x ) { int tmp = 0; for( ; x; x -= x & -x ) tmp += C[x]; return tmp; }void solve( ) { for( register int i = 1; i <= tail; i++ ) { if( !seg[i].k ) ans += query( seg[i].r - 1 ) - query( seg[i].l ); else modify( seg[i].l, seg[i].k ); }}int main( ) { scanf( "%d", &n ); for( register int i = 1; i <= n; i++ ) { scanf( "%d%d", &p[i].x, &p[i].y ); lsh[i].x = p[i].x; lsh[i].id = i; } sort( lsh + 1, lsh + n + 1, cmp0 ); int cnt = 0; lsh[0].x = -2147483640; for( register int i = 1; i <= n; i++ ) { if( lsh[i].x != lsh[ i - 1 ].x ) cnt++; p[lsh[i].id].x = cnt; } build(); sort( seg + 1, seg + tail + 1, cmp3 ); solve(); printf( "%d", ans + n ); return 0;}
阅读全文
0 0
- [BZOJ 1818] CQOI2010 内部白点
- BZOJ 1818 [Cqoi2010]内部白点
- BZOJ 1818 Cqoi2010 内部白点 树状数组
- 1818: [Cqoi2010]内部白点
- 1818: [Cqoi2010]内部白点
- bzoj 1818: [Cqoi2010]内部白点 (扫描线+线段树)
- 【bzoj1818】[Cqoi2010]内部白点
- 【bzoj1818】[Cqoi2010]内部白点
- [BZOJ1818] [Cqoi2010]内部白点
- bzoj1818[Cqoi2010]内部白点
- 【bzoj1818】[Cqoi2010]内部白点
- bzoj1818: [Cqoi2010]内部白点
- bzoj1818: [Cqoi2010]内部白点
- 【bzoj1818】 CQOI2010内部白点 树状数组计数
- BZOJ1818: [Cqoi2010]内部白点 树状数组+离散化
- [BZOJ1818][Cqoi2010]内部白点(扫描线+线段树)
- BZOJ1818 [Cqoi2010]内部白点 扫描线/线段求交
- 【bzoj 1816】: [Cqoi2010]扑克牌
- 论文解读Focal Loss for Dense Object Detection
- 关于git 分支的使用心得
- 动态规划合并排序问题
- 机器学习基本介绍
- HTML中如何让控件居中
- BZOJ 1818 [Cqoi2010]内部白点
- 互信息(mutual information)
- 挖矿详细过程
- spark搭建
- bzoj4419[Shoi2013]发微博
- WordPress免插件实现蜘蛛爬行日志分析
- 总线驱动模型
- 前端框架vue.js系列(10):生命周期钩子函数
- (转)android activity之间传递bean类型数据