Codeforces 1325 D. Ehab the Xorcist (思維/構造) /詳解

D. Ehab the Xorcist
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
Given 2 integers u and v, find the shortest array such that bitwise-xor of its elements is u, and the sum of its elements is v.

Input
The only line contains 2 integers u and v (0≤u,v≤1018).

Output
If there’s no array that satisfies the condition, print “-1”. Otherwise:

The first line should contain one integer, n, representing the length of the desired array. The next line should contain n positive integers, the array itself. If there are multiple possible answers, print any.

Examples
inputCopy
2 4
outputCopy
2
3 1
inputCopy
1 3
outputCopy
3
1 1 1
inputCopy
8 5
outputCopy
-1
inputCopy
0 0
outputCopy
0

題意:
給出u,v,讓你給出一個長度最短的數組使得各元素的異或和等於u,和等於v。

思路:

  1. 很明顯,分類討論:
  2. 如果u>v這時候u的高位爲1而小於v的任何數在這一位都不是1,因此無解;
  3. 如果u==v && v ==0,那麼答案爲一個空數組;
  4. 如果u==v && v !=0 ,那麼答案爲本身uv選任一,即1 u 。
  5. 剩下的情況就需要思考一下,首先特殊情況上面都考慮了,接下來就是我們構造特殊數組,很明顯兩個相同數的異或和等於0,那麼我們就肯定可以構造出u^0=u,這個0由兩個(v-u)/2組成,就同時滿足了u+(v-u)=v的條件。
  6. 注意這個時候可以發現如果(v-u) 是一個奇數,那麼答案也是無解的;
  7. 因爲題目求的是最短的數組,那麼什麼時候存在長度爲2的數組呢?就是我們上面所說的u^0=u,擴展開來就是 u xor x xor x = u, x=(v-u)/2 ;
  8. 我們可以嘗試把u和一個x合併,那麼就變成了 (v-u)/2 和 (v+u)/2 ,判斷是否符合條件,如果不符合條件就輸出長度爲3的情況就ok了。
  9. 簡單來說,如果有解肯定有一組答案爲u+x+x 其中x=(v-u)/2 ,那麼如果有兩個數的答案 我們設爲a ,b 則 a xor b=(u xor x) xor x , a+b=(u+x)+x 那麼判斷是否存在a即判斷(u^x)是否等於u+x 。
  10. 如果有什麼講的不清楚的歡迎留言私信交流~

代碼1:

#include<bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f
#define mod 1000000007
#define PI acos(-1)
#define fi first
#define se second
#define lowbit(x) (x&(-x))
#define mp make_pair
#define pb push_back
#define ins insert
#define si size()
#define E exp(1.0)
#define fixed cout.setf(ios::fixed)
#define fixeds(x) setprecision(x)
#pragma GCC optimize(2)
using namespace std;
inline ll read(){ll s=0,w=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();return s*w;}
void put1(){ puts("YES") ;}void put2(){ puts("NO") ;}void put3(){ puts("-1"); }
ll qp(ll a,ll b, ll p){ll ans = 1;while(b){if(b&1){ans = (ans*a)%p;--b;}a =
(a*a)%p;b >>= 1;}return ans%p;}ll Inv(ll x,ll p){return qp(x,p-2,p);}
ll Cal(ll n,ll m,ll p){if (m>n) return 0;ll ans = 1;for(int i = 1; i <= m; ++i)
ans=ans*Inv(i,p)%p*(n-i+1)%p;return ans%p;}

const int manx=2e5+5;

int main(){
    ll u=read(),v=read();
    if(u>v || ( (v-u)&1 )) {
        put3();
        return 0;
    }
    else if(u==v){
        if(!u) cout<<0;
        else cout<<1<<" "<<u;
        return 0;
    }
    ll x=(v-u)/2,y=(v+u)/2;
    if(((x^y)==u) && x+y==v) cout<<2<<endl<<x<<" "<<y<<endl;
    else{
        cout<<3<<endl;
        cout<<u<<" "<<x<<" "<<x<<endl;
    }
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章