题意:
题目给出 (q) 个询问,问有向图上 (u) 是否可以到达 (v),其中图上的边 (u
ightarrow (u+v)) 存在的条件是 (u&v=v) 。
想法:
- 考虑条件 (u&v=v) 如何才能成立,发现只要对于二进制位上的 (1), (v) 有的 (u) 都有即可。
- 让 (u) 到达 (v),就是通过一些加法,让两个数相等即可。
- 若 (u>v),显然不可达。
- 若 (u=v),显然可达。
- 若 (u<v),对于两个二进制串,我们发现一定可以通过符合条件的加法让低位上的 (1) 变到高位上的 (1),并且二进制中 (1) 的数量只能变少不能变多,综上,也就得出一个结论:计算 (u) 和 (v) 的二进制中 (1) 的个数,做一个前缀和,对于每一位必须$ v1[i]>=v2[i]$ 能保证 (u) 到 (v) 。
代码:
int v1[50],v2[50];
int main()
{
int q,u,v;
cin>>q;
while(q--){
mem(v1,0);
mem(v2,0);
scanf("%d%d",&u,&v);
if(u>v){
puts("NO");
}else{
for(int i=0;i<=30;i++){
if((u>>i)&(1)){
v1[i]=1;
}
}
for(int i=0;i<=30;i++){
if((v>>i)&(1)){
v2[i]=1;
}
}
for(int i=1;i<=30;i++){
v1[i]+=v1[i-1];
v2[i]+=v2[i-1];
}
int k=1;
for(int i=0;i<=30;i++){
if(v2[i]>v1[i]){
k=0;
break;
}
}
if(k){
puts("YES");
}else{
puts("NO");
}
}
}
}