Ehab the Xorcist CodeForces - 1325D
原题链接
考察:构造
思路:
异或和为u,数值和为v.如何判断不可能成立?
- u>v 即不成立.很明显因为u是v的不进位加法.
- u&1 != v&1 .正如上面说u是v的不进位加法.进位是不会改变奇偶性的.理性证明就是 v = u + 2*(u&v) u&v得到u哪些位置该进位,把它们左移一位即可.
那么如何构造最短序列呢?我们需要构造异或和为u,那么u二进制为1的地方一定要有奇数个1.很明显先在序列构造一个u.那么接下来变成了数值和 = v-u,异或和 = 0.需要最短,构造两个v-u>>1即可.
但这样和样例1不符合,原因是样例1只在u二进制为0处增加一些1,在构造相应位置为1的另一个数,序列长度可缩短为2.如何快速求出满足条件的1?可以发现假设另一个数为x. u+x+x = v && x&u==0 即可满足构造长度为2的序列条件.
Code
#include <iostream>
#include <cstring>
using namespace std;
typedef long long LL;
LL n,m;
void solve()
{
if(!m) {puts("0");return;}
if(n==m) {printf("%d\n%lld\n",1,n);return;}
if(n>m||n%2!=m%2) {printf("%d\n",-1);return;}
LL d = m-n>>1ll;
if(!(d&n)) printf("%d\n%lld %lld\n",2,d,n+d);
else printf("%d\n%lld %lld %lld\n",3,d,d,n);
}
int main()
{
scanf("%lld%lld",&n,&m);
solve();
return 0;
}