返回顶部

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;
    }
    
posted @ 2021-03-26 19:01  _Kolibri  阅读(58)  评论(0)    收藏  举报