zoukankan      html  css  js  c++  java
  • codeforces 1325D 位运算+思维

    ok

     

     题意:给了两个数u,v(1e18),输出一个长度为n的数组,使得该数组异或等于u,相加等于v。

    思路: 当v大于u的时候无结果,v=u的时候分情况,如果u=0,输出0,否则输出1和u。

      根据异或的规律,我们可以先让u和0异或成为u,则满足了第一个条件,如果还想满足第二个条件,则要根据v-u的值来处理。把v-u平均分在u和0的二进制同时为0的位置上,即使得u+a 等于0+a,使得(u+a)^(0+a)等于u,且u+a+0+a即u+2a为v,但是v-u不一定能为偶数,如果为奇数,经验证,是不可能有解的,所以v-u为奇数的时候输出-1。

    如何把(v-u)/2 = a平均分到u和0上使得(u+a)^(0+a)等于u呢,u的二进制有1有0,0的二进制只有0,只需要把a的二进制求出来,如果a的二进制和u的二进制没有存在同一位置都为1的情况(如果都为1,异或为0,但是0的二进制为0,加上了a则为1,加上了之后(u+a)^(0+a)遍不再等于u了),直接输出2,a,v-a。如果存在都为1,则输出3,u,a,a即为最优解。

        #include <iostream>
        #include <cmath>
        #include <cstdio>
        #include <cstring>
        #include <string>
        #include <map>
        #include <iomanip>
        #include <algorithm>
        #include <queue>
        #include <stack>
        #include <set>
        #include <vector>
        //const int maxn = 1e5+5;
        #define ll long long
        #define inf  0x3f3f3f3f
        #define FOR(i,a,b) for( int i = a;i <= b;++i)
        #define bug cout<<"--------------"<<endl
         
        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;}
    
        using namespace std;
        int a[1000000],b[1000000];
        int main()
        {
            ll u,v;
            cin>>u>>v;
            ll tmp = (v - u)/2;
            int t1 = 0,t2 = 0;
    
            ll temp = u;
    
            while(temp)
            {
                a[++t1] = temp%2;
                temp /= 2;
            }
        /*    for(int i = 1;i <= t1; ++i)
            {
                cout<<a[i]<<" ";
            }*/
            if((v-u) % 2 == 1 || (v-u) < 0)
            {
                cout<<-1<<endl;
            }
            else if(v-u == 0)
            {
                if(u == 0)
                    cout<<0<<endl;
                else 
                {
                    cout<<1<<endl;
                    cout<<u<<endl;
                }
                
            }
            else 
            {
                ll hhh = tmp;
                while(hhh)
                {
                    b[++t2] = hhh%2;
                    hhh /= 2;
                }
                int flag = 0;
                for(int i = 1;i <= t1; ++i)
                {
                    if(a[i] == b[i] && a[i] == 1)
                    {
                        flag = 1;
                        break;
                    }
                }
                if(flag == 0)
                {
        /*            ll ans = 1;
                    ll maxx = max(t1,t2);
                    for(int i = maxx;i >= 1; --i)
                    {
                        b[i] += a[i];
                        if(b[i] == 0)
                        {
                            ans *= 2;
                        }
                        else if(b[i] == 1)
                        {
                            ans = ans * 2 + 1;
                        }
                    }*/
                    ll ans = v-tmp;
                    cout<<2<<endl;
                    cout<<ans<<" "<<tmp<<endl;
                }
                else if(flag == 1)
                {
                    cout<<3<<endl;
                    cout<<u<<" "<<tmp<<" "<<tmp<<endl;
                }
            }
    
        }
  • 相关阅读:
    Eclipse常用插件推荐
    Open Source Search Engines in Java
    Java: convert a file to a byte array, then convert byte array to a file.
    常用的Eclipse插件介绍
    一个搜索引擎周边的blog
    java文件读取。(单字节读取和按行读取读取)
    im4java
    csv格式读取通用类
    java以流方式下载文件struts2.x版_心灵的港湾_百度空间
    Jetty/Feature/Jetty Maven Plugin
  • 原文地址:https://www.cnblogs.com/jrfr/p/12864602.html
Copyright © 2011-2022 走看看