[KSN2021] Binary Land

本文介绍了如何利用二进制特性,通过建立虚点并运用并查集数据结构,解决关于数字连通性的BinaryLand问题。通过实例代码展示了如何查找最高位为1且后续有0的数字间的连通路径,以及如何利用并查集维护这些连通性。
摘要由CSDN通过智能技术生成

题目链接:[KSN2021] Binary Land


我们可以发现,如果一个数字最高位之后有一个0,那么是可以连向某个对应位置最高位为1的数字。

然后这个不难想到可以对每一个二进制位建立虚点。

我们发现如果这个虚点有作用,那么一定是某个数字最高位是这个,并且某个数字最高位之后某个0是这个。然后并查集维护连通性即可。


AC代码:

#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+10;
int n,a[N],b[N],f[N],vis[N];
int find(int x){return x==f[x]?x:f[x]=find(f[x]);}
void merge(int x,int y){
	x=find(x),y=find(y);
	if(x!=y) f[x]=y,b[y]+=b[x];
}
signed main(){
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i];
	for(int i=1;i<=n;i++) cin>>b[i];
	for(int i=1;i<N;i++) f[i]=i;
	for(int i=1;i<=n;i++){
		int mx=0;
		for(int j=0;j<=30;j++) if(a[i]>>j&1) mx=j;
		vis[mx]|=1;
		for(int j=0;j<mx;j++) if(!(a[i]>>j&1)) vis[j]|=2;
	}	
	for(int i=1;i<=n;i++){
		int mx=0;
		for(int j=0;j<=30;j++) if(a[i]>>j&1) mx=j;
		if(vis[mx]==3) merge(i,n+mx+1);
		for(int j=0;j<mx;j++) if(!(a[i]>>j&1)&&(vis[j]==3)) merge(i,n+j+1);
	}
	for(int i=1;i<=n;i++) printf("%lld\n",b[find(i)]);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值