您的位置:首页 > 其它

Codeforces Round #379 (Div. 2) F. Anton and School

2016-11-16 20:17 381 查看

F. Anton and School

time limit per test : 2 seconds

memory limit per : 256 megabytes

Anton goes to school, his favorite lessons are arraystudying. He usually solves all the tasks pretty fast, but this time the teacher gave him a complicated one: given two arrays b and c of length n, find array a, such that:



where a and b means bitwise AND, while a or b means bitwise OR.

Usually Anton is good in arraystudying, but this problem is too hard, so Anton asks you to help.

Input

The first line of the input contains a single integers n (1 ≤ n ≤ 200 000) — the size of arrays b and c.

The second line contains n integers bi (0 ≤ bi ≤ 109) — elements of the array b.

Third line contains n integers ci (0 ≤ ci ≤ 109) — elements of the array c.

Output

If there is no solution, print  - 1.

Otherwise, the only line of the output should contain n non-negative integers ai — elements of the array a. If there are multiple possible solutions, you may print any of them.

Examples

input

4
6 8 4 4
16 22 10 10


output

3 5 1 1


input

5
8 25 14 7 16
19 6 9 4 25


output

-1


题意

bi=(ai&a1)+(ai&a2)+...+(ai&an)

ci=(ai|a1)+(ai|a2)+...+(ai|an)

给定n及bi,ci数组,求ai数组。

分析

aba&ba|b
0000
0101
1001
1111
根据上表可以得出(a&b)+(a|b)=(a+b) ,在a、b取值0、1时成立。

令aik表示ai二进制第k位的数字,即aik=(ai&2k?1:0)

此时ai=Σ310aik∗2k ,ai取值范围为 [0,109]

ai&aj=Σ310(aik&ajk)∗2k (1)

ai|aj=Σ310(aik|ajk)∗2k (2)

(1)+(2)得: (ai&aj)+(ai|aj)=Σ310(aik&ajk+aik|ajk)∗2k

由于aik、ajk均为0或1

故根据上述结论(a&b)+(a|b)=(a+b) ,得:

(ai&aj)+(ai|aj)=Σ310(aik+ajk)∗2k

故易得(ai&aj)+(ai|aj)=(ai+aj) ,其中ai、aj为正整数

根据上述结论(ai&aj)+(ai|aj)=(ai+aj)

得:bi+ci=Σn1ai+n∗ai

n个n元一次方程必有唯一解或无解。

对于有解情况,此处仍需验证是否满足b、c数组。

对于验证b、c数组。暴力匹配显然O(N2)

考虑aik与、a1k、a2k...ank的关系;

若aik为0,对于and操作,Σnj=1(aik&ajk)=0

若aik为0,对于or操作,Σnj=1(aik&ajk)=Σnj=1ajk

若aik为1,对于and操作,Σnj=1(aik&ajk)=Σnj=1ajk

若aik为1,对于or操作,Σnj=1(aik&ajk)=n

故对于aik(1≤i≤n) ,仅需预处理Σnj=1ajk ,即可在O(logn)的时间判断每个aik

#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
int b
,c
,a
,k[32],n;
long long sum = 0;
bool solve()
{
if(sum % (2*n)) return false;
sum /= (2*n);
for(int i=0,A;i<n;i++)
{
A = b[i] + c[i] - sum;
if(A < 0 || A % n)  return false;
a[i] = A / n;
}
//----------validate a[]---------//
for(int i=0;i<n;i++)
for(int j=0;j<31;j++)
if(a[i] & (1ll << j))
k[j] += (1ll<<j);
for(int i=0;i<n;i++)
{
int sumb = 0,   sumc = 0;
for(int j=0;j<31;j++)
{
if(a[i] & (1ll<<j))
sumb += k[j],
sumc += (1ll<<j)*n;
else
sumc += k[j];
}
if(sumb != b[i] || sumc != c[i])    return false;
}
//----------validate end-----------//
return true;
}
int main()
{
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d",&b[i]),  sum += b[i];
for(int i=0;i<n;i++)
scanf("%d",&c[i]),  sum += c[i];
if(solve())
for(int i=0;i<n;i++)
printf("%d ",a[i]);
else    printf("-1");
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  codeforces round379 acm