异或

问题描述

给定数列{An}

求  lowbit( AixorAj

其中,lowbit(x)=(x) and (-x)

输入格式

输出格式

样例输入

样例输出

数据范围

题解

Lowbit的含义是取出这个数字二进制下最低位的1

对于xor,当参加运算的两个数不同时为1

那么lowbit(AixorAj)就是取出二进制下不相同的最低位

如果是用模拟之类的算法,大概就是从低位到高位枚举找到两个数二进制下不相同的最低位。

然后就想到了字典树。。。

然而我做这题的时候完全忘了有字典树这种东西

由于是从低位到高位比较,把所有数字从低位到高位插入01字典树,记录每个结点被覆盖的次数,当一个数字走到某一个节点时,因为要求的是不相同的最低位,这个结点对答案是没有贡献的,他的兄弟结点对答案才有贡献。树上的节点都是01结点,仅仅取出结点被覆盖的次数是不够的,要根据结点的深度还原成原数。

 

 

 1 #include <cstdio>
 2 #define ll long long
 3 const ll maxn=199907210507;
 4 int n,cnt=1,f[12000015][2],num[12000015];
 5 ll a[100005],ans;
 6 void add(ll x)
 7 {
 8     int now=1,i,j;
 9     for (i=0;i<60;i++)
10     {
11         j=((x&(1ll<<i))>>i);
12         if (!f[now][j]) f[now][j]=++cnt;
13         num[f[now][j]]++;
14         now=f[now][j];
15     }
16     return;
17 }
18 int main()
19 {
20     int i,j,k,now;
21     scanf("%d",&n);
22     for (i=1;i<=n;i++)
23       scanf("%lld",&a[i]);
24     for (i=1;i<=n;i++) add(a[i]);
25     for (i=1;i<=n;i++)  
26       for (now=1,j=0;j<60;j++)
27       {
28         k=((a[i]&(1ll<<j))>>j);
29         ans=(ans+(1ll<<j)%maxn*num[f[now][k^1]]%maxn)%maxn;
30         now=f[now][k];
31         }
32       printf("%lld\n",ans);
33       return 0;
34 }

 

转载于:https://www.cnblogs.com/rabbit1103/p/9756945.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值