题意:给定一个长度为n的序列,计算得他们的和是S,异或和是P,你可以往序列中加入三个数,最后令S==2*P成立。
思路1:因为一个数异或上自己就是0,则先加一个P,则变成 S+P 和 0 ,再加一个 S+P,因为0异或任何数=任何数,所以就变成了2*(S+P)和S+P,满足题意。
思路2:若S<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<<' '<<' '; continue; } cout<<2<<' '; cout<<xr<<" "<<xr+sum<<' '; } return 0; }
思路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; }