Rinne Loves Xor

题目描述

链接:https://ac.nowcoder.com/acm/contest/5505/B来源:牛客网

Rinne 最近学习了位运算相关的知识,她想运用自己学习的知识发明一个加密算法。

链接:https://ac.nowcoder.com/acm/contest/5505/B来源:牛客网

1588837052771

现在她想用程序来实现这个过程,你能帮帮她吗?由于输出可能太大,你只需要输出每个 \(C_i\) 模 10^9+7的结果即可。

输入描述:

第一行一个整数 N,表示数组 A 和 B 的长度。第二行 N 个整数表示数组 A。第三行 N 个整数表示数组 B。

输出描述:

输出一行 N 个整数,表示加密后的数组 C。

示例1

输入

[复制]

10
65605 70259 77306 43823 61443 98602 9261 7662 46394 83019
81393 5966 61479 24259 92528 96132 35859 47981 11702 71736

输出

[复制]

15796 166270 623824 1132402 1650729 2445262 3256941 4150718 5106184 6353038

备注:

N≤10^5,ai≤10^9

\(C_i\)这个式子,前两项都是可以O(1)算的。后面的项,考虑二进制每一位的贡献,相当于每次加上前i-1个\(B_i\)与当前数二进制位数字不同的所有位权和。

所以预处理一下\(A_i,B_i\)\(sum[i][j]\)表示前i位第j位是1的个数,不是1的个数就有\(i-sum[i][j]\)了,

代码

#include <iostream>
#include <cstdio>
#include <cstring>
#define int long long
using namespace std;
const int N=100010,mod=1e9+7;
typedef long long LL;
int a[N],b[N],c[N],power[40],n;
int fa[N][40],fb[N][40];
void calc(int x,int a[]){
    for(int i=0;i<=30;++i){
        if(x&(1<<i)){
            a[i]++;
        }
    }
}
signed main(){
    power[0]=1;
    for(int i=1;i<=30;++i){
        power[i]=power[i-1]*2;
    }
    cin>>n;
    for(int i=1;i<=n;++i) {
        cin>>a[i];
        calc(a[i],fa[i]);
        for(int j=0;j<=30;++j){
            fa[i][j]+=fa[i-1][j];
        }
    }
    for(int i=1;i<=n;++i) {
        cin>>b[i];
        calc(b[i],fb[i]);
        for(int j=0;j<=30;++j){
            fb[i][j]+=fb[i-1][j];
        }
    }
    for(int i=1;i<=n;++i){
        c[i]=(LL)(c[i-1]+(LL)(a[i]^b[i])%mod)%mod;
        for(int j=0;j<=30;++j){
            if(!(a[i]&(1<<j))){
                c[i]=(LL)(c[i]+(LL)fb[i-1][j]*power[j]%mod)%mod;
            }
            else {
                c[i]=(LL)(c[i]+(LL)(i-1-fb[i-1][j])*power[j]%mod)%mod;
            }
            if(!(b[i]&(1<<j))){
                c[i]=(LL)(c[i]+(LL)fa[i-1][j]*power[j]%mod)%mod;
            }
            else {
                c[i]=(LL)(c[i]+(LL)(i-1-fa[i-1][j])*power[j]%mod)%mod;
            }
        }
    }
    for(int i=1;i<=n;++i){
        cout<<c[i]<<" ";
    }
    return 0;
}

posted @ 2020-05-07 16:02  0x4f  阅读(131)  评论(0编辑  收藏  举报