ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

CF1715D 2+ doors

2022-08-21 04:00:08  阅读:128  来源: 互联网

标签:doors val int 条件 CF1715D 数组 ans 字典


简要题意

对于一个数组 \(a\),给定 \(Q\) 个限制条件,每个条件给出 \(i,j,x\) 使得 \(a_i|a_j=x\)。

构造数组使其字典序最小。

Solution

以下 \(ans_i\) 表示最后我们构造出来的答案数组。

考虑一个最宽松的限制条件,我们有一个 \(b\) 数组,在最开始,\(b\) 在二进制意义下全是 \(1\)。

对于每个条件,我们令 \(b_i=b_i\&x,b_j=b_j\&x\)。

显然,\(b\) 数组是答案最宽松的条件,即 \(ans_i\subseteq b_i\)。

也就是说,若一定存在解,则 \(b_i\) 必然是一组合法解。

现在要求字典序最小,我们从前往后构造答案。

考虑当前构造位 \(i\)。

为了让字典序最小,对于一个限制 \(\{a_i|a_j=x,(i<j)\}\),我们应尽可能的让 \(ans_j\) 完成要求,\(ans_j\) 能完成的部分即为 \(x\&b_j\)。

剩余的部分,即 \((x\) \(^\) \((x\&b_j))\),则不得不让 \(ans_i\) 来完成,于是 \(ans_i\) 必须或上这一部分。

但是注意,\(ans_j\) 并不是一定要完成 \(x\&b_j\)。

因为 \(ans_i\) 也有可能在其他条件的迫害下不得不完成了一部分 \(x\)。

于是我们对于 \(\{a_i|a_j=x,(i>j)\}\),再让 \(ans_i|=(x\&ans_i)\) 来完成剩余的限制即可。

由于每一步都是必要的,所以他是最小的。

至于 \(\{a_i|a_j=x,(i=j)\}\),则 \(ans_i=x\) 是必然的。

复杂度 \(O(n+q)\)。

#include<bits/stdc++.h>
#include<vector>
const int N=200010;
int a[N],b[N],ans[N];
struct node{
	int to,val;
};
std::vector<node>p[N];
signed main(){
	int n,q;
	scanf("%d%d",&n,&q);
	for(int i=1;i<=n;i++)a[i]=(1<<30)-1;
	int x,y,z;
	for(int i=1;i<=q;i++){	
		scanf("%d%d%d",&x,&y,&z);
		a[x]=z&a[x],a[y]=z&a[y];
		p[x].push_back(node{y,z}),p[y].push_back(node{x,z});
	}
	for(int i=1;i<=n;i++){
		for(node j:p[i]){
			if(i==j.to)ans[i]|=j.val;
			else if(j.to>=i){
				ans[i]|=((j.val^(j.val&a[j.to]))&a[i]);
			}
			else {
				ans[i]|=((j.val^(j.val&ans[j.to]))&a[i]);
			}
		}
	}
	for(int i=1;i<=n;i++)printf("%d ",ans[i]);
	return 0;
}

标签:doors,val,int,条件,CF1715D,数组,ans,字典
来源: https://www.cnblogs.com/Qzong/p/16609259.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有