1818: [Cqoi2010]内部白点

Time Limit: 10 Sec  Memory Limit: 64 MB
Submit: 704  Solved: 344
[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

HINT

 

题解 :

  -1的情况很好搞,在纸上画画就看出来了。(黄学长博客中有证明:http://hzwer.com/1836.html )

        之后我们发现,其实只用找有多少个白点上下左右都为黑点。

  然后我们就想到了可以用扫描线。。。

  把每个竖线和横线找到。

  从下往上扫描,

  遇到竖线的下端点就 让坐标+1。

  遇到横线就去统计 在 l~r 中的和。

  遇到竖线的上端点就 让坐标 -1。

  这个用树状数组维护一下即可。

代码和对拍:

  丑陋的对拍:

 #include<bits/stdc++.h>
using namespace std;
#define INF 1e9
int a[][],X[],Y[];
int main()
{
int sum,i,j,x,y,xx,yy,xx1,yy1,dx,dy,n,pd;
scanf("%d",&n);
xx=-INF;yy=-INF;xx1=INF;yy1=INF;
for(i=;i<=n;i++){scanf("%d %d",&X[i],&Y[i]);xx=max(xx,X[i]);yy=max(yy,Y[i]);xx1=min(xx1,X[i]);yy1=min(yy1,Y[i]);}
dx=(int)fabs(xx1);dy=(int)fabs(yy1);
for(i=;i<=n;i++)
{
X[i]+=dx;Y[i]+=dy;
a[X[i]][Y[i]]=;
}
sum=n;
for(i=xx1+dx;i<=xx+dx;i++)
{
for(j=yy1+dy;j<=yy+dy;j++)
{
if(a[i][j]==)
{
pd=;
x=i;y=j;
while(x<=xx+dx){if(a[x][y]==){pd++;break;}x++;}
x=i;y=j;
while(y<=yy+dy){if(a[x][y]==){pd++;break;}y++;}
x=i;y=j;
while(x>=xx1+dx){if(a[x][y]==){pd++;break;}x--;}
x=i;y=j;
while(y>=yy1+dy){if(a[x][y]==){pd++;break;}y--;}
if(pd==)sum++;
}
}
}
printf("%d",sum);
return ;
} #include<bits/stdc++.h>
using namespace std;
bool vis[][];
int add=;
int main()
{
srand(time());
int n,i,x,y;
n=rand()%+;
printf("%d\n",n);
for(i=;i<=n;i++)
{
while()
{
x=rand()%-;y=rand()%-;
if(vis[x+add][y+add]==false)
{
vis[x+add][y+add]=true;
break;
}
}
printf("%d %d\n",x,y);
}
return ;
}

     AC程序

 #include<bits/stdc++.h>
using namespace std;
#define MAXN 100010
struct node
{
int x,y;
}p[MAXN];
struct NODE
{
int x,y,pos;
}pp[MAXN];
struct Au
{
int l,r,t;
}s[MAXN*];//这一定要开三倍.
int BIT[MAXN],n,xx[MAXN];
int read()
{
int s=,fh=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')fh=-;ch=getchar();}
while(ch>=''&&ch<=''){s=s*+(ch-'');ch=getchar();}
return s*fh;
}
bool cmp1(NODE a,NODE b)
{
if(a.y==b.y)return a.x<b.x;
return a.y<b.y;
}
bool cmp2(NODE a,NODE b)
{
if(a.x==b.x)return a.y<b.y;
return a.x<b.x;
}
bool cmp3(Au a,Au b)
{
if(p[a.l].y==p[b.l].y)return p[a.l].x<p[a.l].x;
return p[a.l].y<p[b.l].y;
}
int lowbit(int o){return o&(-o);}
void Add(int k,int add)
{
while(k<=n)
{
BIT[k]+=add;
k+=lowbit(k);
}
}
int Sum(int k)
{
int sum=;
while(k>)
{
sum+=BIT[k];
k-=lowbit(k);
}
return sum;
}
int main()
{
int i,cnt,sum,cx,wx,wx1;
n=read();
for(i=;i<=n;i++){p[i].x=read();p[i].y=read();xx[i]=p[i].x;pp[i].x=p[i].x;pp[i].y=p[i].y;pp[i].pos=i;}
sort(pp+,pp+n+,cmp1);//按纵坐标从小到大排,纵坐标相等按横坐标从小到大排.(处理出来横线.)
cnt=;
for(i=;i<n;i++)//存储横线要存左右端点坐标.
{
if(pp[i].y==pp[i+].y)
{
s[++cnt].l=pp[i].pos;s[cnt].r=pp[i+].pos;s[cnt].t=;
}
}
sort(pp+,pp+n+,cmp2);
for(i=;i<n;i++)//存储竖线只用存上下端点.
{
if(pp[i].x==pp[i+].x)
{
s[++cnt].l=pp[i].pos;s[cnt].r=pp[i].pos;s[cnt].t=;//下端点.
s[++cnt].l=pp[i+].pos;s[cnt].r=pp[i+].pos;s[cnt].t=-;//上端点.
}
}
sort(s+,s+cnt+,cmp3);
/*for(i=n;i>1;i--)
{
if(p[s[i].l].y==p[s[i-1].l].y)
}*/
memset(BIT,,sizeof(BIT));sum=n;
sort(xx+,xx+n+);
cx=unique(xx+,xx+n+)-(xx+);
//sort(yy+1,yy+n+1);
//cy=unique(yy+1,yy+n+1)-(yy+1);
for(i=;i<=cnt;i++)
{
if(s[i].t==)
{
wx=lower_bound(xx+,xx+cx+,p[s[i].r].x)-(xx+);
wx1=lower_bound(xx+,xx+cx+,p[s[i].l].x)-(xx+);
sum+=(Sum(wx)-Sum(wx1+));
}
else
{
wx=lower_bound(xx+,xx+cx+,p[s[i].l].x)-(xx+);
//if(wx==0&&xx[1]==p[s[i].l].x)wx=1;
Add(wx+,s[i].t);
}
}
printf("%d",sum);
fclose(stdin);
fclose(stdout);
return ;
}

  

id

Bzoj1818: [Cqoi2010]内部白点 && Tyvj P2637 内部白点 扫描线,树状数组,离散化的更多相关文章

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

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

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

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

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

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

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

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

  5. BZOJ 3196 Tyvj 1730 二逼平衡树 ——树状数组套主席树

    [题目分析] 听说是树套树.(雾) 怒写树状数组套主席树,然后就Rank1了.23333 单点修改,区间查询+k大数查询=树状数组套主席树. [代码] #include <cstdio> ...

  6. 【bzoj3224】【Tyvj 1728】 普通平衡树 树状数组

    您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入$x$数2. 删除$x$数(若有多个相同的数,因只删除一个)3. 查询$x$数的排名(若有多个相同的数,因输出最小 ...

  7. BZOJ - 3224 Tyvj 1728 普通平衡树 (treap/树状数组)

    题目链接 treap及树状数组模板题. treap版: #include<bits/stdc++.h> using namespace std; typedef long long ll; ...

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

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

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

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

随机推荐

  1. 下载youku视频(python3)

    https://github.com/chenfengyuan/download-youku-video 用tornado写的下载脚本, 从flvcd.com得到下载地址. 因为我这边连youku的速 ...

  2. URL重写 UrlRewrite

    为什么要URL重写? 1.有利于SEO,带参数的URL权重较低: 2.地址看起来更正规,推广uid 伪静态:看起来像普通页面,而非动态生成的页面. 原理:在Global.asax的Applicatio ...

  3. AOP学习过程中遇到的问题汇总

    jdk版本问题:     在spring较低的版本中,仅支持jdk1.5到1.7版本,由于我本机安装的是jdk1.8,所以在调试的时候就会提示jdk版本要高于1.5.于是换成spring4.0,在co ...

  4. ubuntu 安装 桌面 awesome

    受了ubuntu 12.04自带的桌面,运行太卡了 http://www.linuxzen.com/awesometmuxgnomedoda-zao-gao-xiao-linuxzhuo-mian-h ...

  5. 『奇葩问题集锦』npm install 报错 node-pre-gyp ERR! node-pre-gyp -v v0.6.25

    gyp ERR! configure error gyp ERR! stack Error: Can't find Python executable "python", you ...

  6. ubuntu下的supervisor启动express失败问题

    ubuntu下apt-get install nodejs后的启动命令是nodejs,而不同于windows下的node 所以我在supervisor启动express的时候出现了问题 提示如下: / ...

  7. iphone 屏幕投射到Mac上

    在实际的工作中,我们往往需要演示iPhone上面的程序,但是由于手机屏幕太小,无法同时给很多人看,这时候就需要进行屏幕投射.目前我需要实现的是投射到Mac上.我使用有线USB和无线Airplay两种方 ...

  8. DM8168 环境搭建(1)

    参考<DM81xx_DVR_RDK_Install_Guide.pdf> location:/dvrrdk/DVRRDK_04.01.00.02/dvr_rdk/docs 1,准备工作: ...

  9. 不用第三个变量,将a,b两个值互换,会出现什么样的异常?

    1 相互加减 a = a + b; b = a - b; a = a - b; 但会出现异常 如果a+b超过a类型的范围,俗称溢出异常. 2 指针操作交换地址 3 异或操作 转自网络搜索的答案

  10. Java多线程初学者指南(12):使用Synchronized块同步变量

    我们可以通过synchronized块来同步特定的静态或非静态方法.要想实现这种需求必须为这些特性的方法定义一个类变量,然后将这些方法的代码用synchronized块括起来,并将这个类变量作为参数传 ...