Codeforces Global Round 13 D. Zookeeper and The Infinite Zoo (思维,位运算)

-
题意:对于两个数\(u\)和\(v\),如果\(u\)&\(v\)=\(v\),那么就代表\(u\)可以走到点\(u+v\),现在你可以对任意两个数进行操作,给你\(q\)个询问,每次问你\(u\)是否可以走到\(v\).
-
题解:其实不难发现,如果\(u\)&\(v\)=\(v\),那么\(v\)一定是不大于\(u\)的,并且\(v\)对应二进制上的每一位\(1\),\(u\)都必须要有,这样我们得到的\(u+v\)就一定是可以通过\(u\)二进制上的\(1\)左移得到,这样就不难发现,如果\(x\)可以走到\(y\),那么\(y\)的二进制对应的前缀就一定要比\(x\)大.具体看代码.
-
代码:
#include <bits/stdc++.h> #define ll long long #define fi first #define se second #define pb push_back #define me memset #define rep(a,b,c) for(int a=b;a<=c;++a) #define per(a,b,c) for(int a=b;a>=c;--a) const int N = 1e6 + 10; const int mod = 1e9 + 7; const int INF = 0x3f3f3f3f; using namespace std; typedef pair<int,int> PII; typedef pair<ll,ll> PLL; ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;} ll lcm(ll a,ll b) {return a/gcd(a,b)*b;} int main(){ int q; cin>>q; while(q--){ int u,v; cin>>u>>v; if(u>v) {cout<<"NO\n";continue;} int cnt_u=0,cnt_v=0; bool flag=true; rep(i,0,30){ if((1<<i)&u) cnt_u++; if((1<<i)&v) cnt_v++; if(cnt_v){ if(!cnt_u){ flag=false; break; } cnt_u--; cnt_v--; } } if(flag) cout<<"YES\n"; else cout<<"NO\n"; } return 0; }
𝓐𝓬𝓱𝓲𝓮𝓿𝓮𝓶𝓮𝓷𝓽 𝓹𝓻𝓸𝓿𝓲𝓭𝓮𝓼 𝓽𝓱𝓮 𝓸𝓷𝓵𝔂 𝓻𝓮𝓪𝓵
𝓹𝓵𝓮𝓪𝓼𝓾𝓻𝓮 𝓲𝓷 𝓵𝓲𝓯𝓮

浙公网安备 33010602011771号