タイトル説明
シンガポール動物園には新しいアトラクションがあります:無限動物園。
Infinite Zooは、1,2,3、…というラベルの付いた無限の数の頂点を持つグラフで表すことができます。u&v = vの場合に限り、頂点uから頂点u + vへの有向エッジがあります。ここで、&はビット単位のAND演算を示します。グラフには他のエッジはありません。
Zookeeperにはq個のクエリがあります。i番目のクエリで、彼女は、有向エッジを通過して頂点uiから頂点viに移動できるかどうかを尋ねます。
入力
最初の行には整数q(1≤q≤105)—クエリの数が含まれています。
次のq行のi番目には、2つの整数ui、vi(1≤ui、vi <230)が含まれます—Zookeeperによって作成されたクエリです。
出力
qクエリのi番目について、Zookeeperが頂点uiから頂点viに移動できる場合は、「YES」を1行で出力します。それ以外の場合は「NO」を出力します。
あなたはどんな場合でもあなたの答えを印刷することができます。たとえば、答えが「はい」の場合、出力「はい」または「はい」も正解と見なされます。
例
入力
5
1 4
3 6
1 6
6 2
5
出力
YES
YES
NO
NO
YES
注意
頂点1、2、3、4、5、6のサブグラフを以下に示します。
タイトル説明
シーケンス1、2、3、...、正の無限大があります。u&v = vの場合に限り、uはu + vに移動できます。q個のクエリがあり、各クエリは2つのポイントuとvを与え、uがvに到達できるかどうかを尋ねます。
トピック分析
まず、uがvに到達できる場合、vはuより大きくなければならないことを判断できます。すべてのエッジがu−> u +ある数u-> u +ある数であるためU ->>u+1つの数字が得られます。条件1:v>=u
次に、各ポイント間の接続条件を分析します。
3を例にとると、3は3 + 1、3 + 2、および3 +3に到達できます。数値(2進数)の1つの位置はすべて左に移動できますが、右には移動できないことがわかります。
条件2:u和v(二进制)的1从右向左进行一一对应,如果u中的所有1所对应的v中的1,全部都大于u中对应的1的话,那么u可以到v。
例:6(110)は6 + 2、6 + 4、および6 +6に到達できます。しかし、6は7(111)と9(1001)に到達できません。
コードは以下のように表示されます
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <map>
#include <unordered_map>
#include <queue>
#include <vector>
#include <set>
#include <bitset>
#include <algorithm>
#define LL long long
#define PII pair<int,int>
#define x first
#define y second
using namespace std;
const int N=1e4+5,mod=1e9+7;
bool check(int u,int v)
{
int a=0,b=0; //a记录u中当前未匹配的个数,b记录v中当前未匹配的个数
for(int i=0;i<31;i++)
{
if(u>>i&1) a++; //如果当前位上有1,那么进行记录
if(v>>i&1) b++;
if(b) //如果b中有元素了
{
if(!a) return false; //但是a中还没有元素,那么说明与当前位匹配的u中的1要大于该位,不合法
a--,b--; //否则匹配成功
}
}
return true;
}
int main()
{
int q;
scanf("%d",&q);
while(q--)
{
int u,v;
scanf("%d%d",&u,&v);
if(u<=v&&check(u,v)) puts("YES"); //利用条件1,2进行匹配
else puts("NO");
}
return 0;
}