一个无限大的有向图,按如下方式建边,问 \(u\) 是否可达 \(v\) 。
显然可达保证 \(u \le v\) 。
之后就没法一眼了,画图考虑一些特殊点。
画个图可以发现,\(2\) 的幂次只能走到二的幂次。进而我们想到,将建边方式看成一种移位方式,每次都可能将某位 \(1\) 左移一位或者不动。也就是形如 \(01 \rightarrow 10\) 的变化。
之后又发现,一些非 \(2\) 的整数幂也可以到 \(2\) 的幂次上,如 \(110 \rightarrow 1000\) 。我们发现对于多个一,我们总可以通过一些操作在左移的同时减少它们的个数。
因此我们得到结论,如果 \(u\) 从低到高 \(1\) 的个数总不少于 \(v\) 的个数,并且 \(u \le v\) 则一定可达。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<vector> #include<set> #include<queue> #include<map> #include<stack> #include<string> #include<random> #include<bitset> #include<iomanip> #define yes puts("yes"); #define inf 0x3f3f3f3f #define ll long long #define linf 0x3f3f3f3f3f3f3f3f #define ull unsigned long long #define endl '\n' #define int long long #define rep(i,a,n) for(int i = a;i <= n;i++) #define per(i,n,a) for(int i = n;i >= a;i--) using namespace std; mt19937 mrand(random_device{}()); int rnd(int x) { return mrand() % x;} typedef pair<int,int> PII; const int MAXN =10 + 2e5 ,mod=1e9 + 7; void solve() { int u,v; cin >> u >> v; bitset<32> bs1(u),bs2(v); int cnt = 0; rep(i,0,30) { cnt += bs1[i] - bs2[i]; if(cnt < 0 || u > v) { cout << "NO\n"; return; } } cout << "YES\n"; } signed main() { ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); int T;cin>>T; while(T--) solve(); return 0; }
import sys from math import * input = sys.stdin.readline def mrd(): return [int(x) for x in input().split()] def rd(): return int(input()) MAXN = 2 * 10**5 + 5 INF = 10**16 * 2 mod = 10**9 + 7 #----------------------------------------------------------------------------------# def solve(): u,v = mrd() cnt = 0 for i in range(0,30): cnt += (u >> i & 1) - (v >> i & 1) if cnt < 0 or u > v: print("NO") return print("YES") if __name__ == "__main__": for _ in range(rd()): solve()