[Codeforces Round #816 (Div. 2)] D. 2+ doors

这次Div.2比之前我打的有些要难啊,前三道题就耗了好多时间,D题干脆摆烂了。。。

还是太逊了

对于一个x,有x|yi=zi,那么我们设num[x]=z1&z2&z3....

zi的第pos位为0,则说明xyi的第pos位一定为0;若zi的第pos位为0,则说明xyi第pos至少 有一个为1,即x的第pos位可能为1,yi的第pos位可能为1

所以,对于初始的num[x],它就是第x个数的所有答案中最大的

既然答案要求字典序最小,那么遍历第一个数到最后一个数,将当前数记为x,将所有与x有题目给定的关系的yz都遍历一遍,记 t|=zi&(~num[yi])

zi&(~num[yi])显然意味着在当前这个关系中,x必须取到的1

所以t|=zi&(~num[yi])也就意味这对于x的所有关系,x必须取的数

前文说了对于初始的num[x],它是第x个数的所有答案中最大的,所以这时求出的t也一定 是第一个数最小的答案

再将num[x]更新为t,继续上述过程,得到的就是字典序最小的答案

#include<bits/stdc++.h>
#define pr pair<int,int>
#define fi first
#define se second
using namespace std; 
const int N=1e5+5,M=2e5+5;
int n,q,num[N];
vector<pr> cdt[N]; 
int main(){
	scanf("%d%d",&n,&q);
	for(int i=1;i<=n;++i) num[i]=(1<<30)-1; 
	for(int i=1,x,y,z;i<=q;++i){
		scanf("%d%d%d",&x,&y,&z);
		num[x]&=z,num[y]&=z;
		cdt[x].push_back(pr(y,z));
		cdt[y].push_back(pr(x,z));
	}
	for(int i=1;i<=n;++i){
		int t=0;
		for(int j=0;j<cdt[i].size();++j){
			int x=cdt[i][j].fi,s=cdt[i][j].se;
			t|=(s&(~num[x]));
			if(x==i){ t=s; break; }
		}
		printf("%d ",(num[i]=t));
	}
	return 0;
}

posted @   LuoyuSitfitw  阅读(69)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示