【codeforces 734F】Anton and School

【题目链接】:http://codeforces.com/problemset/problem/734/F

【题意】

给你两个数组b和c;
然后让你找出一个非负数组a满足题中所给关系;

【题解】

有个结论吧;
(x and y + x or y)=x+y
然后把那n个式子全都加起来;
令d[i]=b[i]+c[i]···①;

d[i]=na[i]+a
再把所有的①式加起来;
d=2na
则由③式可得
a=d/(2n)
再代入②式
a[i]=(d[i]d/(2n))/n

a[i]=(2nd[i]d)/(2n2)
对于a[i]<0或a[i]不为整数的情况.
返回无解就好;
但是做完这些还不够;
还是可能错解..
还要验证一下得到的a[i]是不是能够按照那个规则得到b[i]和c[i];
但是直接强算是O(N2)的复杂度;
这里一位一位的算比较快;
我们算出所有的aj在第i位上上为1的个数kj;
然后就有
这里写图片描述
这里写图片描述
这里看我们可以通过Ai,j和kj快速获取Bi,j和Ci,j

这里写图片描述
然后根据得到的Ci,j和Bi,j;
根据位权,乘上相应的2的x次方;
然后累加起来;
看看c数组和b数组和所给的c、b数组是否相同.

【Number Of WA

0

【完整代码】

#include <bits/stdc++.h>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define LL long long
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define ms(x,y) memset(x,y,sizeof x)
#define Open() freopen("F:\rush.txt","r",stdin)
#define Close() ios::sync_with_stdio(0),cin.tie(0)

typedef pair<int,int> pii;
typedef pair<LL,LL> pll;

const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
const double pi = acos(-1.0);
const int N = 2e5+100;

int n;
LL b[N],c[N],d[N],sumd = 0,a[N],ans[N];
int B[N][65],C[N][65];
LL bin[65];

void out()
{
    cout << -1 << endl;
    exit(0);
}

int main()
{
    //Open();
    Close();//scanf,puts,printf not use
    bin[0] = 1;
    rep1(i,1,62)
        bin[i] = bin[i-1]<<1;
    cin >> n;
    rep1(i,1,n)
        cin >> b[i];
    rep1(i,1,n)
    {
        cin >> c[i];
        d[i] = b[i]+c[i];
        sumd += d[i];
    }
    rep1(i,1,n)
    {
        a[i] = 1LL*2*n*d[i]-sumd;
        LL temp = 1LL*2*n*n;
        if (a[i]%temp!=0)  out();
        a[i]/=temp;
        if (a[i]<0) out();
        ans[i] = a[i];
    }
    LL ma = *max_element(a+1,a+1+n);
    int limit = 0;
    while (ma)
    {
        ma>>=1;
        limit++;
    }
    rep1(i,0,limit-1)
    {
        int k = 0;
        rep1(j,1,n)
            if (a[j]&bin[i])
                k++;
        rep1(j,1,n)
        {
            if (a[j]&bin[i])
            {
                B[j][i]+=k,C[j][i]+=n;
            }
            else
                //a[j]%1==0
                C[j][i]+=k;
        }
    }
    rep1(i,1,n)
    {
        LL tb = 0;
        rep1(j,0,limit-1)
            tb = tb+B[i][j]*bin[j];
        LL tc = 0;
        rep1(j,0,limit-1)
            tc = tc+C[i][j]*bin[j];
        if (tb!=b[i]||tc!=c[i])
            out();
    }
    rep1(i,1,n)
        cout << ans[i] <<' ';
    //init??????
    return 0;
}
原文地址:https://www.cnblogs.com/AWCXV/p/7626316.html