Codeforces Round #379 (Div. 2) F. Anton and School
2016-11-16 20:17
381 查看
F. Anton and School
time limit per test : 2 secondsmemory 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数组。
分析
a | b | a&b | a|b |
---|---|---|---|
0 | 0 | 0 | 0 |
0 | 1 | 0 | 1 |
1 | 0 | 0 | 1 |
1 | 1 | 1 | 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 Round #404(Div. 2)D. Anton and School - 2【组合数学+思维】好题!好题!
- 【数论】Codeforces Round #404 (Div. 2)(D)Anton and School - 2
- Codeforces Round #404 (Div. 2):D. Anton and School - 2(范德蒙德恒等式)
- Codeforces Round #379 (Div. 2) F. Anton and School
- Codeforces Round #379 (Div. 2) F. Anton and School
- Codeforces Round #404 (Div. 2) D. Anton and School - 2 数学
- Codeforces Round #404 (Div. 2) D. Anton and School - 2(范德蒙恒等式)
- Codeforces Round #404 (Div. 2) D. Anton and School - 2(组合数学)
- Codeforces Round #379 (Div. 2) F. Anton and School
- Codeforces Round #404 (Div. 2) D. Anton and School - 2
- #404 (div2)Anton and School - 2
- Codeforces Round #379 (Div. 2) F Anton and School(数学)
- Codeforces Round #379 (Div. 2) F. Anton and School
- Codeforces Round #404 (Div. 2) D. Anton and School - 2 排列组合好题
- 【组合数】【乘法逆元】 Codeforces Round #404 (Div. 2) D. Anton and School - 2
- codeforces round 404 div2 D Anton and School - 2 组合数学
- Codeforces Round #404 (Div. 2) D. Anton and School - 2 [范德蒙恒等式]
- 组合数学——Codeforces Round #404 (Div. 2) D. Anton and School - 2
- Codeforces Round #404 (Div. 2) D. Anton and School - 2 前缀的后缀、 范德蒙恒等式、容斥
- Codeforces Round #379 (Div. 2) D. Anton and Chess 模拟