CF734F. Anton and School

思路:

性质题。

 (a&b)+(a|b)=a+b。于是可以构造出一组满足这一位满足 $(b[i]+c[i])$ 的唯一一组解,在对于这组解去验证答案是否正确,若不正确则无解。

以下代码:

#include<bits/stdc++.h>
#define il inline
#define LL long long
#define _(d) while(d(isdigit(ch=getchar())))
using namespace std;
const int N=2e5+5;
int n,b[N],a[N],num[30],c[N],d[N];LL sum;
il int read(){
   int x,f=1;char ch;
   _(!)ch=='-'?f=-1:f;x=ch^48;
   _()x=(x<<1)+(x<<3)+(ch^48);
   return f*x;
}
int main()
{
    n=read();
    if(n==1){
        int x=read(),y=read();
        if(x!=y)return puts("-1"),0;
        else return printf("%d\n",x),0;
    }
    for(int i=1;i<=n;i++)b[i]=c[i]=read();
    bool pd=0;
    for(int i=1;i<=n;i++){
        int x=read();if(b[i]>x)pd=1;
        b[i]+=x,sum+=b[i];d[i]=x;
    }
    if(pd)return puts("-1"),0;
    if(sum%(2*n))return puts("-1"),0;
    sum=sum/(2*n);
    for(int i=1;i<=n;i++)if((b[i]-sum)%n)return puts("-1"),0;
    for(int i=1;i<=n;i++)a[i]=(b[i]-sum)/n;
    for(int i=1;i<=n;i++){
        for(int j=0;j<30;j++)if(a[i]&(1<<j))num[j]++;
    }
    for(int i=1;i<=n;i++){
        int num1=0,num2=0;
        for(int j=0;j<30;j++){
            if(a[i]&(1<<j))num1+=1ll*num[j]*(1<<j),num2+=1ll*n*(1<<j);
            else num1+=0,num2+=1ll*num[j]*(1<<j);
        }
        if(num1!=c[i]||num2!=d[i])return puts("-1"),0;
    }
    for(int i=1;i<=n;i++)printf("%d ",a[i]);
    return 0;
}
View Code

 

posted @ 2019-03-14 08:34  Jessiejzy  阅读(369)  评论(0编辑  收藏  举报