B Rinne Loves Xor 异或题

题意:

 

 思路:假如直接计算,那么复杂度会达到n^2

    于是,我们需要一种复杂度较低的做法;    

    假如有这样一个二进制数 1 1 1

    然后我们有另一个二进制数0 0 1

    那么这两个数的异或计算方式为:1 1 1^0 0 1

       也可以为:(0 0 1)^ 0 0 1+0 1 0^ 0 0 1 + 1 0 0 ^0 0 1(即,把前面的数一位一位拆开分开计算)

       于是,我们可以想到另一种做法,就是把数按二进制位置存下来;

     然后根据这一个位置的0 1 数量来计算和即可

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int mod=1e9+7;
 5 const int N=1e5+5;
 6 int a[N],b[N],A[40][2],B[40][2];
 7 ll c[N];
 8 int main()
 9 {
10     int n;
11     scanf("%d",&n);
12     for(int i=1;i<=n;i++)
13         scanf("%d",&a[i]);
14     for(int i=1;i<=n;i++)
15         scanf("%d",&b[i]);
16     c[0]=0;
17     for(int i=1;i<=n;i++){
18         c[i]=c[i-1]+(a[i]^b[i])%mod;
19         for(int j=0;j<=30;j++){
20             int t=(a[i]>>j)&1;
21             c[i]=(c[i]+1LL*B[j][1-t]*(1<<j)%mod)%mod;
22             t=(b[i]>>j)&1;
23             c[i]=(c[i]+1LL*A[j][1-t]*(1<<j)%mod)%mod;
24             A[j][(a[i]>>j)&1]++;
25             B[j][(b[i]>>j)&1]++;
26         }
27     }
28     for(int i=1;i<=n;i++)
29         printf("%lld%c",c[i]%mod,i==n?'\n':' ');
30     return 0;
31 }
View Code

 

posted @ 2020-05-05 11:06  古比  阅读(125)  评论(0编辑  收藏  举报