Codeforces Round #379 (Div. 2) F. Anton and School
2016-11-17 12:55
507 查看
题意:给出两个长度为n(n<=2e5)的数组b和c(0<=b[i],c[i]<=1e9),求出一个数组a,使得
b[x]=∑(a[x] and a[i])
c[x]=∑(a[x] or a[i])
如果不存在解,输出-1
首先要知道a&b + a|b = a+b,关于这点自己模拟下就懂了。
然后这个问题就简单了,试着把b和c加起来会发现
b[i]+c[i]==∑(a[x]+a[i])n∗a[x]+∑a[i]
可以得到 ∑(b[i]+c[i])=2n∗∑a[i]
处理下就可以得到数组a了,然后反代回去验证下b和c就OK了。
这里验证可以按位统计,只需要记录当前位有几个0/1,就可以在n*lg(x)的时间内计算完毕了。
buff传送门:
http://meopass.blog.163.com/blog/static/25837605920161016105549976/
b[x]=∑(a[x] and a[i])
c[x]=∑(a[x] or a[i])
如果不存在解,输出-1
首先要知道a&b + a|b = a+b,关于这点自己模拟下就懂了。
然后这个问题就简单了,试着把b和c加起来会发现
b[i]+c[i]==∑(a[x]+a[i])n∗a[x]+∑a[i]
可以得到 ∑(b[i]+c[i])=2n∗∑a[i]
处理下就可以得到数组a了,然后反代回去验证下b和c就OK了。
这里验证可以按位统计,只需要记录当前位有几个0/1,就可以在n*lg(x)的时间内计算完毕了。
/* *********************************************** Author :axp Created Time :2016/11/16 14:58:06 TASK :F.cpp LANG :C++ ************************************************ */ #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <vector> #include <queue> #include <set> #include <map> #include <string> #include <cmath> #include <cstdlib> #include <ctime> using namespace std; typedef long long ll; const int inf = 1<<30; const int md = 1e9+7; const int N = 2e5+10; int n,m; int T; int b ; int c ; ll a ; const int M = 60; int num[M]; ll fand(ll x) { ll re=0; for(int i=0;i<M;i++) if(x&(1ll<<i)) re+=num[i]*(1ll<<i); return re; } ll fo(ll x) { ll re=0; for(int i=0;i<M;i++) if(x&(1ll<<i)) re+=n*(1ll<<i); else re+=num[i]*(1ll<<i); return re; } bool solve() { ll sum=0; for(int i=0;i<n;i++)sum+=b[i]+c[i]; //cout<<sum<<endl; if(sum%(n*2))return 0; sum/=n*2; for(int i=0;i<n;i++) { a[i]=b[i]+c[i]-sum; if(a[i]<0 || a[i]%n)return 0; a[i]/=n; int t=a[i],now=0; while(t) { if(t&1)num[now]++; now++; t/=2; } } for(int i=0;i<n;i++) { if(fand(a[i])!=b[i])return 0; if(fo(a[i])!=c[i])return 0; } return 1; } int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); scanf("%d",&n); for(int i=0;i<n;i++)scanf("%d",&b[i]); for(int i=0;i<n;i++)scanf("%d",&c[i]); bool ans=solve(); if(ans) { for(int i=0;i<n;i++) printf("%I64d%c",a[i],(i==n-1?10:' ')); } else puts("-1"); return 0; }
buff传送门:
http://meopass.blog.163.com/blog/static/25837605920161016105549976/
相关文章推荐
- 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 #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 #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 #253 (Div. 2) A. Anton and Letters