Make Good-cf

题意:给定一个长度为n的序列,计算得他们的和是S,异或和是P,你可以往序列中加入三个数,最后令S==2*P成立。

 

思路1:因为一个数异或上自己就是0,则先加一个P,则变成  S+P0 ,再加一个 S+P,因为0异或任何数=任何数,所以就变成了2*(S+P)S+P,满足题意。

 

思路2S<2P,则可以往里面加两个相等的数为(2P-S)/2,令题目条件成立。需要满足的条件是1. 2P-S是偶数2. S<2P。先满足第二个条件,如果S>2P,则先往里面加一个巨大的数,例如序列是 2 2 ,S=4,P=0, 加一个w进去,则条件二可以满足。对于条件一来说,2P已经是偶数了,要让S变成偶数,则控制加进去的w就行,若原来是偶数,加进去奇数,原来是奇数,加进去偶数,所以两个条件都可以满足了。

 

思路1代码:

 

#include<iostream>
using namespace std;
int t,n;
int main()
{
    cin>>t;
    while(t--){
        cin>>n;
        int x;
        long long int sum=0,xr=0;
        for(int i=1;i<=n;i++){
            cin>>x;
            sum+=x;
            xr^=x;
        }
        if(sum==2*xr){
            cout<<0<<'\n'<<'\n';
            continue;
        }
        cout<<2<<'\n';
        cout<<xr<<" "<<xr+sum<<'\n';
    }
    return 0;
}
View Code

 

思路2代码:

#include<iostream>
using namespace std;
const int maxn=1e5+10;
typedef long long ll;
int t,n;
ll a[maxn];
int main(){
    cin>>t;
    while(t--){
        cin>>n;
        ll s=0,p=0;
        for(int i=1;i<=n;i++){
            cin>>a[i];
            s+=a[i];
            p^=a[i];
        }
        if(s==2*p){
            cout<<0<<endl;
            cout<<endl;
            continue;
        }
        ll w=(1ll<<50)+s%2;
        s+=w;p^=w;
        cout<<3<<endl;
        cout<<w<<" "<<(2*p-s)/2<<" "<<(2*p-s)/2<<endl;
    }
    return 0;
}
View Code

 

  

posted @ 2019-12-31 11:35  艾尔夏尔-Layton  阅读(158)  评论(0编辑  收藏  举报