CF 1567B MEXor Mixup

题意概述:对于一个非负整数序列,给出不属于该整数序列的最小非负整数a,该整数序列的异或和b,求出该整数序列最少所含的元素个数

分析:

一个非常有意思的题。

一开始容易拘泥于:“如何求出被异或的数” 容易出现错误

但我们不需要具体数字,所以选择转而去分析异或规则带来的性质

对于异或而言,运算规则为相同为0,相异为1,那么很容易可以得出,对于一个特定的数而言,一定可以构造出两个数,异或之后结果为该特定数,且这样的构造有无穷组

(构造的数是可以相等的,不会破坏最小非负整数的性质)

那么我们考虑,对于a!=0的情况(a=0是简单的,即如果b为0构造两个相同正整数,如果是1取1即可)

首先小于a的所有非负整数一定在序列之中,先求出这一些数的异或和x(可以提前预处理降低复杂度)

判断x与b的关系,如果x=b则结果为a即这些数构成的序列成立,如果x^a=b,由于a不能处于序列中,则a需要由额外两个数构造,结果应为x+2,否则则只需要额外的一个数即可,结果即为x+1

code:

#include<bits/stdc++.h>
using namespace std;
int T;
int p[100],q[100];
int d[300005];
int a,b;
int l,r,ans;
int v,x;
bool flag;
inline int cal (int x,int b)
{
    if (x==0) p[++p[0]]=x;
    while (x)
    {
       p[++p[0]]=x%2;
       x>>=1;
    }
    if (b==0) q[++q[0]]=b;
    while (b)
    {
       q[++q[0]]=b%2;
       b>>=1;
    }
}
int main()
{
    cin>>T;
    d[0]=0;
    for (int i=1;i<=300000;++i)
    {
        d[i]=d[i-1]^i;
    }
    while (T--)
    {
       cin>>a>>b;
       if (a==0)
       {
          if  (b==0) cout<<2<<endl;
          else cout<<1<<endl;
          continue;
       }
       x=d[a-1];
       memset(p,0,sizeof(p));
       memset(q,0,sizeof(q));
       cal(x,b);
    //   for (int i=p[0];i>=1;--i) cout<<p[i]; cout<<‘ ‘;
     //  for (int i=q[0];i>=1;--i) cout<<q[i];  cout<<endl;
       flag=false; ans=0;
       l=0; r=0;
   /*    while (l<p[0]||r<q[0])
       {
          ++l; ++r;
          if (p[l]==q[r]) ans=ans*2;
          else ans=ans*2+1;
       }*/
       //cout<<ans<<‘ ‘;
       v=a;
       if (d[a-1]==b) cout<<v<<endl;
       else
       {
           if (d[a]==b) cout<<v+2<<endl; else cout<<v+1<<endl;
       }
    }
    return 0;
}

 

CF 1567B MEXor Mixup

上一篇:亿图图示 免费VIP会员兑换码激活码礼品券!!!


下一篇:心有所觉,但亦作不解。