题目传送门

位运算

设题目中序列 \(w_1,w_1\& w_2,w_1\& w_2\& w_3,\dots,w_1\& w_2\& \dots \& w_n\) 为序列 \(A\)。

因为是数字一个一个 \(\&\) 到之前的结果上,所以可以知道 \(A\) 序列单调不增。

从给出的样例中发现,似乎没有答案超过 \(2\) 的情况

证明:

假设答案 \(>2\),则说明 \(A\) 序列至少中出现过了 \(0,1,2\),因为 \(A\) 序列单调不增,所以假设当前的 \(A_i\) 为 \(2\),必须后面的数出现 \(1\) 和 \(0\) 才可以。但 \(2\) 的二进制末位为 \(0\),无论怎么 \(\&\) ,后面的数也不可能出现 \(1\),假设不成立,所以答案不可能 \(>2\)。

结论:

答案为 \(0\),\(1\) 或 \(2\)。

判断答案

  • 首先考虑答案为 \(0\) 的情况,即 \(A\) 序列中没有出现过 \(0\):

\(A\) 序列中没有出现过 \(0\),即说明对于所有 \(w\),在二进制下至少有一位都是 \(1\),不然 \(\&\) 后就会变 \(0\)。

那么如何判断是否有一条路径上所有边权在二进制下至少有一位都是 \(1\)?

考虑用并查集维护。因为 \(w<=2^{30}\),所以可以开 \(30\) 个并查集,分别维护每一位上是 \(1\) 的边权所连接的点的集合,然后要判断求的两点是否在其中一张图中连通即可。

  • 再看答案为 \(1\) 的情况,即 \(A\) 序列中出现过 \(0\) 但没有出现过 \(1\):

\(A\) 序列中没有出现过 \(1\),即说明对于 \(A\) 序列前某一部分 \((i<k)\),\(a_i>1\),而 \(a_k\) 及之后都是 \(0\)。

先考虑如何保证 \(A\) 序列前某一部分 \((i<k)\),\(a_i>1\)。这个和答案为 \(0\) 的情况很像,只要所有 \(w_i(i<k)\) 中至少有一位都是 \(1\) 即可。但特别地,这一位不能是末位,否则 \(a_{k-1}\) 就变 \(1\) 了。

然后就只要判断之后是否有一条边可以使 \(\&\) 之后结果为 \(0\) 即可。

如何维护?

先上结论:只要保证末位有一个 \(0\) 即可。先把之前判断答案是否为 \(0\) 的并查集借过来,然后事先找好哪些边权末位为 \(0\),将与这些边相邻的点和一个虚点 \(0\) 连起来。如果后询问中出发点 \(u\) 可以和虚点 \(0\) 连通,那么答案就为 \(1\) 了。

证明:如果后询问中出发点 \(u\) 可以和虚点 \(0\) 连通,就意味着 \(u\) 在某一位上 (不为末位)可经过连续的几个 \(1\),保证了 \(a_i>1\)。然后可以走到一位末位为 \(0\) 的,\(a_i\) 的末位就会变成 \(0\)。之后,因为不存在某一位全部为 \(1\) 的(已经被判掉了),所以可以保证 \(a_i\) 的其他位最终也会变成 \(0\)。

  • 最后,都不是这两种情况的答案就为 \(2\)。

那么,如何方便地实现并查集?

便利の并查集

可以写到一个结构体里。(涨芝士了

比如:

struct DSU{
int fa[100005];
DSU(){for(int i=0;i<=100000;i++)fa[i]=i;} //初始化
int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);} //find
void merge(int x,int y){fa[find(x)]=find(y);} //合并
bool query(int x,int y){return find(x)==find(y);} //判断
}x[35];

合并:

x[i].merge(u,v);

判断联通:

if(x[i].query(u,v))

要开多个并查集时很方便,比写二维数组要清楚。

完整代码

#include<bits/stdc++.h>
using namespace std;
int n,m,q,u,v,w;
bool mark[100005];
struct DSU{ //还是喜欢不压行
int fa[100005];
DSU(){
for(int i=0;i<=100000;i++) fa[i]=i;
}
int find(int x){
if(fa[x]==x) return x;
return fa[x]=find(fa[x]);
}
void merge(int u,int v){
fa[find(u)]=find(v);
return ;
}
bool query(int u,int v){
return find(u)==find(v);
}
}x[35],y[35];
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
scanf("%d%d%d",&u,&v,&w);
for(int j=0;j<30;j++){
if((w>>j)&1) x[j].merge(u,v); //j位是1的连起来
}
if(!(w&1)) mark[u]=mark[v]=1; //末位不是1做标记
}
for(int i=1;i<=30;i++){ //从1开始
y[i]=x[i];
for(int j=1;j<=n;j++){
if(mark[j]) y[i].merge(j,0); //有标记和0连
}
}
scanf("%d",&q);
for(int i=1;i<=q;i++){
scanf("%d%d",&u,&v);
bool fl=0;
for(int j=0;j<30;j++){ //从0开始
if(x[j].query(u,v)){
printf("0\n"),fl=1;
break;
}
}
if(fl) continue;
for(int j=1;j<30;j++){ //从1开始
if(y[j].query(u,0)){
printf("1\n"),fl=1;
break;
}
}
if(fl) continue;
printf("2\n");
}
return 0;
}

特别鸣谢:巨佬 Mine_King代码 帮助我理解了解题方法

查重率 100% qwq

【笔记】CF1659E AND-MEX Walk 及相关的更多相关文章

  1. Effective STL 学习笔记 Item 21:Comparison Function 相关

    Effective STL 学习笔记 Item 21:Comparison Function 相关 */--> div.org-src-container { font-size: 85%; f ...

  2. [论文阅读笔记] Community aware random walk for network embedding

    [论文阅读笔记] Community aware random walk for network embedding 本文结构 解决问题 主要贡献 算法原理 参考文献 (1) 解决问题 先前许多算法都 ...

  3. openresty 学习笔记四:连接mysql和进行相关操作

    openresty 学习笔记四:连接mysql和进行相关操作 毕竟redis是作为缓存,供程序的快速读写,虽然reidis也可以做持久化保存,但还是需要一个做数据存储的数据库.比如首次查询数据在red ...

  4. openresty 学习笔记三:连接redis和进行相关操作

    openresty 学习笔记三:连接redis和进行相关操作 openresty 因其非阻塞的调用,令服务器拥有高性能高并发,当涉及到数据库操作时,更应该选择有高速读写速度的redis进行数据处理.避 ...

  5. Android学习笔记⑤——UI组件的学习TextView相关

    TextView是一个强大的视图组件,直接继承了View,同时也派生出了很多子类,TextView其作用说白了就是在布局中显示文本,有点像Swing编程中的JLabel标签,但是他比JLabel强大的 ...

  6. Hadoop自学笔记(一)常见Hadoop相关项目一览

    本自学笔记来自于Yutube上的视频Hadoop系列.网址: https://www.youtube.com/watch?v=-TaAVaAwZTs(当中一个) 以后不再赘述 自学笔记,难免有各类错误 ...

  7. 《The Linux Command Line》 读书笔记04 Linux用户以及权限相关命令

    Linux用户以及权限相关命令 查看身份 id:Display user identity. 这个命令的输出会显示uid,gid和用户所属的组. uid即user ID,这是账户创建时被赋予的. gi ...

  8. jQuery学习笔记(二):this相关问题及选择器

    上一节的遗留问题,关于this的相关问题,先来解决一下. this的相关问题 this指代的是什么 这个应该是比较好理解的,this就是指代当前操作的DOM对象. 在jQuery中,this可以用于单 ...

  9. [Android学习笔记]理解焦点处理原理的相关记录

    焦点处理相关记录 以下所涉及的焦点部分,只是按键移动部分,不明确包含Touch Focus部分 需解决问题 控件的下一个焦点是哪? 分析思路 当用户通过按键(遥控器等)触发焦点切换时,事件指令会通过底 ...

随机推荐

  1. 「学习笔记」单调队列优化dp

    目录 算法 例题 最大子段和 题意 思路 代码 修剪草坪 题意 思路 代码 瑰丽华尔兹 题意 思路 代码 股票交易 题意 思路 代码 算法 使用单调队列优化dp 废话 对与一些dp的转移方程,我们可以 ...

  2. KingbaseES启动数据库失败后如何分析

    关键字: KingbaseES.sys_ctl.启动日志 一.KingbaseES数据库服务启动 1.1 数据库启动机制 1) 数据库通过sys_ctl工具手工启动数据库服务kingbase. 2) ...

  3. 微信小程序语音提示

    一. 老规矩, 先上demo图:  然后通过 wx.createInnerAudioContext  创建内部 audio 上下文 InnerAudioContext 对象 就能播放 filename ...

  4. 运维利器-ClusterShell

    前言 和ansible类似,但是更加高效 安装 yum install -y clustershell clush命令: clush -a 全部 等于 clush -g all clush -g 指定 ...

  5. torch.meshgrid

    1:https://blog.csdn.net/weixin_39504171/article/details/106356977 2: https://pytorch.org/docs/stable ...

  6. C#,使用FindWindow和FindWindowEx查找窗体和控件

    函数: // Find Window // 查找窗体 // @para1: 窗体的类名 例如对话框类是"#32770" // @para2: 窗体的标题 例如打开记事本 标题是&q ...

  7. [Python]-sklearn.model_selection模块-处理数据集

    拆分数据集train&test from sklearn.model_selection import train_test_split 可以按比例拆分数据集,分为train和test x_t ...

  8. Python数据科学手册-机器学习: 流形学习

    PCA对非线性的数据集处理效果不太好. 另一种方法 流形学习 manifold learning 是一种无监督评估器,试图将一个低维度流形嵌入到一个高纬度 空间来描述数据集 . 类似 一张纸 (二维) ...

  9. logstash 读取MySQL数据到elasticsearch 相差8小时解决办法

    logstash和elasticsearch是按照UTC时间的,kibana却是按照正常你所在的时区显示的,是因为kibana中可以配置时区信息. 具体看这个: logstash 的配置文件添加 fi ...

  10. PPR的断管

    1. 小管径PPR管的断管 2. 大管径PPR管的断管