新加坡动物园有一个新的景点:无限动物园。无限动物园可以用一个具有无限个顶点的图表示,标记为1,2,3,....有一条从顶点u到顶点u + v的有向边当且仅当u&v = v,其中&z表示逐位and操作。图中没有其他边。Zookeeper有q个查询。在第i个查询中,她会问你是否可以通过有向边从顶点u移动到顶点u。输入第一行包含一个整数q (1 <g< 105) -查询的数量。接下来的q行的第i行将包含两个整数u, v (1 <ui,v < 230)-一个Zookeeper的查询。输出对于q个查询中的第i个,如果Zookeeper可以从顶点u移动到顶点o,则输出“YES”,否则输出“NO”。在任何情况下你都可以打印你的答案。例如,如果答案是“YEs”,那么输出的“YEs”或“YEs”也会被认为是正确答案。
Example
input
Copy
5 1 4 3 6 1 6 6 2 5 5
output
Copy
YES YES NO NO YES
题解:
首先根据题中所给条件u如果能到v,u <= v
其次我们观察一下有一条从顶点u到顶点u + v的有向边当且仅当u&v = v
都什么时候可以成立
假设u = 11000
v = 10000
v = 1000
v = 11000
v = 1000时成立
或者这种v = 110000也成立
但是如果有比u低位的1比如11001,11100这种则不会成立
u + v,1的位置只会左移不会右移,所以我们看看,终点二进制位是否会有出现目前累计有一个1,但起点无1的情况即可
#include <cstdio>
#include <cstring>
#include <algorithm>
#include<iostream>
#include<vector>
#include<set>
#include<map>
using namespace std;
int mod = 1e9 + 7;
typedef long long ll;
ll a[5005];
ll b[5005];
int check(int u,int v)
{
int a = 0,b = 0;
for(int i = 0;i < 31;i++)
{
if(u >> i& 1)
a++;
if(v >> i&1)
b++;
if(b)
{
if(!a)
{
return 0;
}
a--;
b--;
}
}
return 1;
}
void solve()
{
int u,v;
cin >> u >> v;
if(u <= v&&check(u,v))
{
cout << "YES\n";
}
else{
cout <<"NO\n";
}
}
signed main()
{
// ios::sync_with_stdio(0);
// cin.tie(0);cout.tie(0);
int t = 1;
cin >> t;
while(t--)
{
solve();
}
}