题意:
给你n对 b[i], c[i], 让你求a[i],不存在输出-1
b[i] = (a[i] and a[1]) + (a[i] and a[2]) + (a[i] and a[3]) +...+ (a[i] and a[n]);
c[i] = (a[i] or a[1]) + (a[i] or a[2]) + (a[i] or a[3]) +...+ (a[i] or a[n]);
and 和 or 是按位与 或

思路:
(a and b) + (a or b) = (a + b) 证明显然
所以把每个b[i]+c[i] = n*a[i] + s, s为所有a的和
这样 就可以解出每个 a[i]了,且解唯一,证明比较显然

但是,解出的解不一定就是正确解!
为什么会这样呢?
因为解方程的时候 把b[i] c[i]看成了一个整体。
也就是他们的和是满足的,但是他们自身可能不满足。
举个例子:n = 1, b[0] = 3, c[0] = 5;
发现用上面的方法是有解的 a[0] = 4, 但是很显然,这个也并不合法

所有我们需要检测每一个b,c是否合法。
n那么大,暴力n方肯定是不行了。
我们要这样操作:
用A[i][j]表示 a[i]的第j位是否为1,顺便求出k[j],k[j]表示所有a中的第j位有多少个1 处理的时间复杂度O(n*logv)
再求出B[i][j], C[i][j]
B[i][j] = (A[1][j] and A[i][j]) + (A[2][j] and A[i][j]) + ... + (A[n][j] and A[i][j]);
C[i][j] = (A[1][j] or A[i][j]) + (A[2][j] or A[i][j]) + ... + (A[n][j] or A[i][j]);
这个不用暴力求,因为我们刚刚已经求出了k[j]
显然地,有下面的式子:
if A[i][j] = 0: B[i][j] = 0, C[i][j] = k[j]
else B[i][j] = k[j], C[i][j] = n

有了B C后我们就能很快的求出b, c了
b[i] = B[i][0]*2^0 + B[i][1]*2^1 + ...
c[i] = C[i][0]*2^0 + C[i][1]*2^1 + ...

最终的时间复杂度O(n*logv), v=max(a1,a2,..,an)

具体代码如下:

 const int maxn =  + ;
LL b[maxn], c[maxn], a[maxn];
LL A[maxn][], B[maxn][], C[maxn][], k[maxn];
LL s;
int n; void init()
{
scanf("%d", &n);
for (int i = ; i < n; i ++) scanf("%lld", b + i);
for (int i = ; i < n; i ++) scanf("%lld", c + i);
} bool check() //返回求出的答案是否合法
{
for (int j = ; j < ; j++)
{
for (int i = ; i < n; i++)
{
A[i][j] = a[i] & (1ll << j) ? : ;
k[j] += A[i][j];
}
}
for (int j = ; j < ; j++)
{
for (int i = ; i < n; i++)
{
if (A[i][j])
{
B[i][j] = k[j];
C[i][j] = n;
}
else
{
B[i][j] = ;
C[i][j] = k[j];
}
}
} for (int i = ; i < n; i++)
{
LL sumB = , sumC = ;
for (int j = ; j < ; j++)
{
sumB += B[i][j] * (1ll << j);
sumC += C[i][j] * (1ll << j);
}
if (sumB != b[i] || sumC != c[i]) return false;
}
return true;
} void solve()
{
bool ans = true;
for (int i = ; i < n; i++)
{
s += b[i] + c[i];
}
if (s % ( * n)) ans = false;
s /= * n;
for (int i = ; i < n; i++)
{
a[i] = (b[i] + c[i] - s) / n;
if ((b[i] + c[i] - s) % n) ans = false;
}
if (!ans || !check()) printf("-1\n");
else
{
for (int i = ; i < n;i ++)
{
printf("%lld ", a[i]);
}
}
} int main()
{
init();
solve();
return ;
}

Codeforces Round #379 (Div. 2) F. Anton and School的更多相关文章

  1. Codeforces Round #379 (Div. 2) D. Anton and Chess 水题

    D. Anton and Chess 题目连接: http://codeforces.com/contest/734/problem/D Description Anton likes to play ...

  2. Codeforces Round #379 (Div. 2) D. Anton and Chess —— 基础题

    题目链接:http://codeforces.com/contest/734/problem/D D. Anton and Chess time limit per test 4 seconds me ...

  3. Codeforces Round #379 (Div. 2) E. Anton and Tree 缩点 直径

    E. Anton and Tree 题目连接: http://codeforces.com/contest/734/problem/E Description Anton is growing a t ...

  4. Codeforces Round #379 (Div. 2) C. Anton and Making Potions 枚举+二分

    C. Anton and Making Potions 题目连接: http://codeforces.com/contest/734/problem/C Description Anton is p ...

  5. Codeforces Round #379 (Div. 2) B. Anton and Digits 水题

    B. Anton and Digits 题目连接: http://codeforces.com/contest/734/problem/B Description Recently Anton fou ...

  6. Codeforces Round #379 (Div. 2) A. Anton and Danik 水题

    A. Anton and Danik 题目连接: http://codeforces.com/contest/734/problem/A Description Anton likes to play ...

  7. Codeforces Round #379 (Div. 2) D. Anton and Chess 模拟

    题目链接: http://codeforces.com/contest/734/problem/D D. Anton and Chess time limit per test4 secondsmem ...

  8. Codeforces Round #379 (Div. 2) E. Anton and Tree —— 缩点 + 树上最长路

    题目链接:http://codeforces.com/contest/734/problem/E E. Anton and Tree time limit per test 3 seconds mem ...

  9. Codeforces Round #379 (Div. 2) C. Anton and Making Potions —— 二分

    题目链接:http://codeforces.com/contest/734/problem/C C. Anton and Making Potions time limit per test 4 s ...

随机推荐

  1. linux 两个文件合并

    可以使用cat命令,有两种实现的方式,一种将两个文件合并的到一个新的文件,另一种将一个文件追加到另一个文件的末尾. 方法一:使用cat命令从文件中读入两个文件,然后将重定向到一个新的文件.这种方法可以 ...

  2. CheckBoxList控件获取多选择,需要遍历

    CheckBoxList控件获取多选择,需要遍历,环境:vs2008 在页面上添加CheckBoxList控件,输入项值 a,b,c,d.然后添加按钮 Button2确定,如何获取CheckBoxLi ...

  3. opacity与RGBA透明的区别

    为什么不使用opacityCSS3 还允许通过opacity 声明来设置元素的透明度.该透明度的值也是一个介于0 到1 之间的小数(如将opacity 设置为0.1 表示为10%透明).但是这种透明度 ...

  4. ACM 暴力搜索题 题目整理

    UVa 129 Krypton Factor 注意输出格式,比较坑爹. 每次要进行处理去掉容易的串,统计困难串的个数. #include<iostream> #include<vec ...

  5. SQLite常用命令总结

    1) 创建数据库文件: >SQLite3 d:\test.db 回车 就生成了一个test.db在d盘. 这样同时也SQLite3挂上了这个test.db 2) 用.help可以看看有什么命令 ...

  6. ajax容易忽视的细节

    用了很长时间的ajax,自己也写过原生ajax请求,但是发现自己对于ajax理解仍然非常肤浅. 1.ajax请求后,服务器会返回数据,返回头中content-type直接影响responseXML,r ...

  7. firefox vimperator插件

    firefox vimperator插件实在是强大,最喜欢的几个功能做个笔记. 如何复制网页上的文字:c进入caret模式,定位cursor到要复制的开始位置--v进入visual模式,用hjkl键选 ...

  8. 一些初级Java错误,不定期增加

    1. Error: Dangling meta character '*' near index 0 对字符串使用split()方法截取 * ? + / | 等字符的时候会报以下异常 Dangling ...

  9. mysql批量替换单字段

    update 表名 set 字段名 =  replace(字段名,'被替换内容','要替换内容'); 指定有人查这个!!!

  10. NPOI读取Excel 数据 转。。。

      public DataTable am_Decode() { DataTable table = new DataTable(); string[] strAscDataList = Direct ...