Codeforces 1325 D - Ehab the Xorcist(思维 + 构造)

题目链接:https://codeforces.ml/contest/1325/problem/D

题意:给你两个正整数 u u u v v v,让你找个正整数序列 a [ ] a[] a[],使的
a [ 1 ] + a [ 2 ] + . . . + a [ n ] = v a[1]+a[2]+...+a[n] = v a[1]+a[2]+...+a[n]=v a [ 1 ] ⨁ a [ 2 ] ⨁ . . . ⨁ a [ n ] = u a[1]\bigoplus a[2]\bigoplus ... \bigoplus a[n] = u a[1]a[2]...a[n]=u

思路:首先考虑几个特殊情况:
1)、 v ≥ u v\geq u vu才有解,因为 a + b = a ⨁ b + 2 × ( a & b ) a + b = a\bigoplus b + 2\times (a \& b) a+b=ab+2×(a&b)
2)、 u = v u = v u=v u = 0 u = 0 u=0时,答案就是一个 0 0 0(最后一个样例);
3)、 u = v u = v u=v u ≠ 0 u \neq 0 u=0时,答案为 { u } \{u\} {u}
接下来我们考虑除了这几个特判之外的情况。
我们令 x = v − u 2 x = \frac{v-u}{2} x=2vu,那么序列 { u , x , x } \{u,x,x\} {u,x,x}一定是答案,
因为 u + x + x = v , u ⨁ x ⨁ x = u u+x+x = v,u\bigoplus x\bigoplus x = u u+x+x=v,uxx=u
又因为我们要求一个正整数序列,所以
4)、 v − u v - u vu不是二的倍数时,无解。
所以我们现在只需要考虑有没有什么样的数对 a , b a,b a,b,满足 a + b = v a+b = v a+b=v a ⨁ b = u a\bigoplus b = u ab=u还是考虑上面说的公式 a + b = a ⨁ b + 2 × ( a & b ) a + b = a\bigoplus b + 2\times (a \& b) a+b=ab+2×(a&b),那么我们可以得到 v = u + 2 × ( a & b ) v = u + 2\times(a\&b) v=u+2×(a&b),这样我们化简一下,可以得到
a & b = v − u 2 = x a\&b = \frac{v-u}{2} = x a&b=2vu=x
因为 a ⨁ b = u a\bigoplus b = u ab=u a & b = x a\&b = x a&b=x,所以我们可以对 a a a b b b一位一位的进行分析,如果(一下 a a a b b b表示 a a a b b b的某一位二进制位)
a = 1 & & b = 1 − > u = 0 , x = 1 a = 1 \&\& b = 1 -> u = 0,x = 1 a=1&&b=1>u=0,x=1
a = 1 & & b = 0 − > u = 1 , x = 0 a = 1\&\&b=0->u=1,x=0 a=1&&b=0>u=1,x=0
a = 0 & & b = 1 − > u = 1 , x = 0 a = 0\&\&b=1->u=1,x=0 a=0&&b=1>u=1,x=0
a = 0 & & b = 0 − > u = 0 , x = 0 a = 0\&\&b=0->u=0,x=0 a=0&&b=0>u=0,x=0
所以如果 a , b a,b a,b有解,那么 u & x = 0 − > u + x = u ⨁ x u\&x = 0->u+x = u\bigoplus x u&x=0>u+x=ux,那么此时数列 { u + x , u } \{u+x,u\} {u+x,u}是符合题意的,因为 u + x + x = v , ( u + x ) ⨁ x = ( u ⨁ x ) ⨁ x = u u+x+x = v,(u+x)\bigoplus x = (u\bigoplus x)\bigoplus x = u u+x+x=v,(u+x)x=(ux)x=u
所以这一题总结一下就是:
1)、 v ≤ u v\leq u vu时无解;
2)、 u = v u = v u=v u = 0 u = 0 u=0时,答案就是一个 0 0 0(最后一个样例);
3)、 u = v u = v u=v u ≠ 0 u \neq 0 u=0时,答案为 { u } \{u\} {u}
4)、 v − u v - u vu不是二的倍数时,无解;
5)、 u & x = 0 u\&x = 0 u&x=0时,解为 { u + x , u } \{u+x,u\} {u+x,u}
6)、 u & x ≠ 0 u\&x\neq 0 u&x=0时,解为 { u , x , x } \{u,x,x\} {u,x,x}
细节好多
这样我们就可以写代码啦:

#include <set>
#include <map>
#include <stack>
#include <queue>
#include <cmath>
#include <vector>
#include <cstdio>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

#define LL long long
#define pii pair<int,int>
#define sd(x) scanf("%d",&x)
#define slld(x) scanf("%lld",&x)
#define pd(x) printf("%d\n",x)
#define plld(x) printf("%lld\n",&x)
#define rep(i,a,b) for(int i = a ; i <= b ; i++)
#define per(i,a,b) for(int i = b ; i >= a ; i--)
#define mem(a) memset(a,0,sizeof(a))
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1
#define fast_io ios::sync_with_stdio(false)

const LL INF = 1e12;
const LL mod = 1e9 + 7;
const int maxn = 2e5 + 7;

int out[maxn];
int u[maxn],v[maxn];

int main() {
    LL u,v;
    while(~scanf("%lld%lld",&u,&v)) {
        if(u > v || (v > u && ((v - u) & 1LL))) pd(-1);
        else if(u == v) {
            if(u == 0) printf("0\n");
            else printf("1\n%lld\n",u);
        } else {
            LL x = (v - u) / 2LL;
            if((u & x) == 0) {
                printf("2\n%lld %lld\n",u + x,x);
            } else {
                printf("3\n%lld %lld %lld\n",u,(v-u)/2LL,(v-u)/2LL);
            }
        }
    }
    return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值