首页 > 其他分享 >Luogu P5816[CQOI2010]内部白点题解

Luogu P5816[CQOI2010]内部白点题解

时间:2022-11-05 19:44:13浏览次数:109  
标签:ch 黑点 题解 线段 白点 P5816 变换 端点 Luogu

Luogu P5816

Description

一个平面直角坐标系内有 \(n\) 个黑点,其余点为白点,将会进行若干次变换,每次变换会把上下左右方向都有黑点的白点变成黑点,直到找不到符合要求的白点。

问最终有多少黑点。若变换过程永不停止,输出 -1

Solution

首先看一个结论:在任何情况下,最多只会变换一次。

简证:假设存在一个点 \(A\),它是经过两次变换得到的,那么它的四个方向中至少有一个点是经过一次变换得到的(否则点 \(A\) 也应当在第一次变换时被染成黑色)。

设这个点为 \(B\),那么点 \(B\) 应当是四个原始的黑点染成黑色的并且是 \(A\) 向 \(B\) 方向上唯一的黑点。

然而这意味着 \(A\) 向 \(B\) 方向就会有另一个原始黑点。矛盾。(如下图,红点即为矛盾点)

image.png

那么问题就转化为:有多少个白点满足其上下左右方向都有黑点。

不难看出,这就是询问将所有水平/竖直方向的点用线段连接起来之后,横竖方向的线段之间能形成多少个交点(在端点处相交不算)。

设一条横着的线段从 \((x_1,y_1)\) 到 \((x_2,y_1)\),另一条竖着的线段从 \((x_3,y_2)\) 到 \((x_3,y_3)\),那么它们能形成交点的充要条件为 \(\begin{cases}x_3 \in [x_1+1,x_2-1] \\ y_1 \in [y_2+1,y_3-1]\end{cases}\)。

于是使用扫描线:将所有横向线段按照 \(y\) 坐标排序后将 \(y\) 轴看作时间轴,把竖着的线段看作单点修改(下端点 \(+1\) 上端点 \(-1\))(相当于表示从下端点到上端点这段时间内,在这条线段的 \(x\) 坐标处有一条线段),此时横着的线段可以看作询问 \([l+1,r-1]\) 之间的和(\(l\) 为区间左端点,\(r\) 为区间右端点)(相当于询问这个区间内有多少条竖着的线段),开一个树状数组维护即可。

但是考虑到坐标范围 \(10^9\),于是先离散化。

Code

#include<cstdio>
#include<algorithm>
const int M=1e5+5;
inline int read(){int x(0),op(0);char ch=getchar();while(ch<'0'||ch>'9')op|=(ch==45),ch=getchar();while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+(ch^48),ch=getchar();return op?-x:x;}
struct line{
	int l,r,h,w;
	bool operator < (const line& rhs){
		return h<rhs.h;
	}
}L[M*3];//luogu的数据好像略水,我在校内OJ上交的时候开2e5会RE,分析之后应该是L数组要开成3e5否则全部是修改操作会炸
struct point{
	int x,y;
}P[M];
bool cmp1(point a,point b){
	if(a.y!=b.y)return a.y<b.y;
	return a.x<b.x;
}
bool cmp2(point a,point b){
	if(a.x!=b.x)return a.x<b.x;
	return a.y<b.y;
}
int n,X[M<<1],Y[M<<1],cnt1,cnt2,ltot,T[M];
int lowbit(int x){return x&(-x);}
void add(int x,int y){
	for(;x<=cnt1;x+=lowbit(x))T[x]+=y;
}
int prefix(int x){
	int ans=0;
	for(;x;x-=lowbit(x))ans+=T[x];
	return ans;
}
int main(){
	n=read();
	for(int i=1;i<=n;++i)P[i].x=X[i]=read(),P[i].y=Y[i]=read();
	//离散化
	std::sort(X+1,X+n+1);
	std::sort(Y+1,Y+n+1);
	cnt1=std::unique(X+1,X+n+1)-X-1;
	cnt2=std::unique(Y+1,Y+n+1)-Y-1;
	for(int i=1;i<=n;++i){
		P[i].x=std::lower_bound(X+1,X+cnt1+1,P[i].x)-X;
		P[i].y=std::lower_bound(Y+1,Y+cnt2+1,P[i].y)-Y;
	}
	//处理出所有横向的线段
	//注意:这里只处理相邻的点,以防算重
	std::sort(P+1,P+n+1,cmp1);
	for(int i=1;i<n;++i)if(P[i].y==P[i+1].y)L[++ltot]=(line){P[i].x,P[i+1].x,P[i].y,0};
	//处理出所有纵向的线段
	std::sort(P+1,P+n+1,cmp2);
	for(int i=1;i<n;++i)if(P[i].x==P[i+1].x){
		L[++ltot]=(line){P[i].x,0,P[i].y,1};
		L[++ltot]=(line){P[i].x,0,P[i+1].y,-1};
	}
	//扫描线
	std::sort(L+1,L+ltot+1); 
	int ans=0;
	for(int i=1;i<=ltot;++i){
		if(L[i].w)add(L[i].l,L[i].w);
		else ans+=prefix(L[i].r-1)-prefix(L[i].l);
	}
	printf("%d\n",ans+n);//注意:答案包括原有黑点
	return 0;
}

标签:ch,黑点,题解,线段,白点,P5816,变换,端点,Luogu
From: https://www.cnblogs.com/pokefunc/p/16860927.html

相关文章

  • python print 打印延迟问题解决
    转载:https://wenku.baidu.com/view/ffc89347bb4ae45c3b3567ec102de2bd9705de56.html?wkts=1667639107060&bdQuery=python+print%E7%AB%8B%E5%8D%B3%E6%89%93%E5%8D%B0......
  • 【题解】洛谷P2946 [USACO09MAR]Cow Frisbee Team S
    这题乍一看是一个朴素的01背包问题,将所有方案的集合按照能力值的和来划分成1~m,然后把m当作体积,把n当作物品数,做一个01背包的代码。于是我兴冲冲地写了代码交上去,然后十组样......
  • accoders NOI #5047. 猜数游戏 题解
    题目描述Alice和Bob玩游戏。Alice有一个\(1~n\)中的正整数\(y\)。Bob不知道这个数。游戏中的每一轮,Bob选一个正整数\(x\),并提问Alice:\(y\)是否大于等于\(x......
  • 「题解」Codeforces 1612F Armor and Weapons
    首先可以不管套件,假定\(n<m\),那么答案不超过\(\mathcal{O}(\logn+\frac{m}{n})\),也就是先倍增把\(n\)造出来,然后一步步造\(m\).答案这么小,那么常见的套路就是把答案......
  • 问题解决:vscode运行python找不到文件
    问题描述:使用VSCode执行Python代码调用其他文件时报FileNotFound错误,终于发现是VSCode工作路径默认是当前文件所在工作区的根目录,而不是当前文件所在目录。发生条件:根......
  • 「题解」牛客练习赛105 F 胖头鱼头胖
    先对每个位置\(i\)对集合幂级数\(x^0+x^1+\cdots+x+x^{a_i}\)FWT,那么询问就是将区间里面所有FWT后的集合幂级数作点积再IFWT后提取\(x^s\)的系数。首先可以通......
  • P2484 [SDOI2011]打地鼠 题解
    P2484[SDOI2011]打地鼠题解目录P2484[SDOI2011]打地鼠题解题目分析思路代码题目P2484[SDOI2011]打地鼠题解分析锤子每次只能将每个洞里打掉一只地鼠,所以对于每......
  • P7365 [CTSC2002]颁奖典礼 题解
    一道神奇的有关网格的DP(一些大佬称其为暴力DP)。这里将“I”字母分为的三个部分称为第一,二,三部分。做法:设fi,j,k,l(l∈[1,3])表示第i行,当前在第l部分,区间[j,k]的......
  • 矩阵树定理学习笔记 & 洛谷 P4111 [HEOI2015]小 Z 的房间 题解
    矩阵树定理拉普拉斯矩阵无边权设无向图\(G\)有\(n\)个结点,则拉普拉斯矩阵\(L\)是一个\(n\timesn\)的矩阵,满足:\(L_{i,i}(i\inG)\)的值为结点\(i\)的度数......
  • 【题解】Luogu P8743 【[蓝桥杯 2021 省 A] 异或数列】
    最近刚好在刷博弈论,看到这道题没有题解,所以刚好来水一发题目链接[蓝桥杯2021省A]异或数列题目描述Alice和Bob正在玩一个异或数列的游戏。初始时,Alice和Bob......