Codefoeces 734F. Anton and School 数学

Codefoeces 734F

题目大意:

给定两个正整数序列(b,c)构造一个正整数序列(a)使其满足

[left{ egin{array}{} b_i=(a_i ext{ and }a_1)+(a_i ext{ and }a_2)+...+(a_i ext{ and }a_n) \ c_i = (a_i ext{ or }a_1)+(a_i ext{ or }a_2)+...+(a_i ext{ or }a_n) end{array} ight. ]

题解:

我们有这么一个性质((a_i ext{ and } b_i)+(a_i ext{ or }b_i)= a+b)
所以我们把所有的(b_i,c_i)加和,得到

[left{ egin{array}{} b_1+c_1 = na_1 + sum{a_i} \ b_2+c_2 = na_2 + sum{a_i} \ ... \ b_n+c_n = na_n + sum{a_i} end{array} ight. ]

然后再把所有的式子加和得到
(sum{a_i} = frac{sum{b_i} + sum{c_i}}{2n})
然后我们可以利用这个解出所有的(a_i)

我也不知道为什么必须对每一位都特殊判定,不过不判定的话下面这组数据过不去
1
3
5
应该是不可行,但是如果不进行数位判定的话会输出4...
哪位大神可以来救救我。。。

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
template<typename T>inline void read(T &x){
	x=0;char ch;bool flag = false;
	while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
	while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
}
inline int cat_max(const int &a,const int &b){return a>b ? a:b;}
inline int cat_min(const int &a,const int &b){return a<b ? a:b;}
const int maxn = 200010;
ll b[maxn],c[maxn],a[maxn];
int cnt[32][2];
int main(){
	int n;read(n);
	ll sum = 0;
	for(int i=1;i<=n;++i) read(b[i]),sum += b[i];
	for(int i=1;i<=n;++i) read(c[i]),sum += c[i];
	if(sum % (n<<1) != 0) return puts("-1");
	sum /= (n<<1);
	for(int i=1;i<=n;++i){
		ll x = b[i] + c[i] - sum;
		if(x < 0 || (x%n != 0)) return puts("-1");
		a[i] = x/n;
		for(int j=0;j<31;++j) ++cnt[j][(a[i]>>j)&1];
	}
	for(int i=1;i<=n;++i){
		for(int j=0;j<31;++j) b[i] -= ((a[i]>>j)&1)*cnt[j][1]<<j;
		if(b[i] != 0) return puts("-1");
	}
	for(int i=1;i<=n;++i){
		printf("%I64d",a[i]);
		if(i != n) putchar(' ');
		else putchar('
');
	} 
	getchar();getchar();
	return 0;
}
原文地址:https://www.cnblogs.com/Skyminer/p/6357538.html