lowbit
来源:互联网 发布:淘宝店铺招牌怎么上传 编辑:程序博客网 时间:2024/06/06 03:23
树状数组(lowbit)
Time Limit:1000ms Memory Limit:128MB
题目描述
这天,LYK在学习树状数组。
当它遇到一个叫lowbit的函数时有点懵逼。lowbit(x)的意思是将x分解成二进制,它的值就是2^k,其中k是最小的满足(x & 2^k)>0的数。(&是二进制中的and运算)
LYK甚至知道lowbit(x)=(x&-x)。但这并没什么用处。
现在LYK有了n个数字,为了使自己更好的理解lowbit是什么意思。它想对所有n^2个二元组求lowbit。具体的,对于一个二元组(ai,aj),它的值为lowbit(ai xor aj) (xor表示异或的意思),那么总共有n^2对二元组,LYK想知道所有二元组的值加起来是多少。
这个答案可能很大,你只需输出这个值对1000000007取模后的结果就可以了。
输入格式(lowbit.in)
第一行一个数n,表示有n个这样的数字
第二行n个数ai
输出格式(lowbit.out)
一个数表示答案
输入样例
5
1 2 3 4 5
输出样例
32
数据范围
对于30%的数据n<=1000
对于另外10%的数据ai<=1
对于再另外10%的数据ai<=3
对于再再另外20%的数据ai<1024
对于100%的数据1<=n<=100000,0<=ai<2^30
读完题面
先看数据范围
n^2的纯暴力可以过30%的数据
常规的暴力分
然而
我们又注意到了
对于另外10%的数据ai<=1
对于再另外10%的数据ai<=3
对于再再另外20%的数据ai<1024
看起来很小啊
试试记录ai的数量
然后再进行暴力
lowbit(a[i] xor a[j])*num[a[i]]*num[a[j]]
这样的感觉
现在
我们能拿到70分了
之后的正解
我自己是想不出来啦……
以下引用
lowbit(x,y)
把x和y都分解成二进制
奇数(二进制末位是1),偶数(二进制末位是0)
lowbit(x^y)=1
把奇数放到左边,假设有x个
把偶数放到右边,假设有y个
x*y*2 对 lowbit起来是等于1
lowbit(x^y)=2
x和y全奇 或者 全偶
假如x和y全奇数
二进制倒数第二位一个是0一个是1
倒数第二位是0 倒数第二位是1
1 2 3 4 5
001 010 011 100 101
001 010
011 100
101
3*2*2 * 1 = 12
011 001 010 100
101
1*2*2 * 2 = 8 1*1*2 * 2=4
101 001
1*1*2 * 4 = 8
分治完之后, 二元组一个在左边,另一个在右边,这样的贡献是很容易统计的
对于每一个数,它只在最多31层中被分治到,总时间复杂度是n*31
正解
#include<iostream>#include<cstring>#include<algorithm>#include<cstdio>#include<cmath>#include<queue>#include<vector>#include<climits>#include<string>#include<cstdlib>#include<ctime>#define MOD 1000000007#define MAXN 999999999#define LL long longusing namespace std;LL a[100005],b[100005],ans;LL n;void work(LL m,LL t){ LL l,r,p,i; if(m<=1||t>=30) return; l=0; for(i=1;i<=m;i++) if(a[i]&(1<<t)) { l++; b[l]=a[i]; } r=l; for(i=1;i<=m;i++) if(!(a[i]&(1<<t))) { r++; b[r]=a[i]; } for(i=1;i<=m;i++) a[i]=b[i]; ans=(ans+(l*(m-l)%MOD)%MOD*(1<<t)%MOD)%MOD; work(l,t+1); p=0; for(i=l+1;i<=r;i++) { p++; a[p]=a[i]; } work(p,t+1);}int main(){ freopen("lowbit.in","r",stdin); freopen("lowbit.out","w",stdout); int i; scanf("%lld",&n); for(i=1;i<=n;i++) scanf("%lld",&a[i]); work(n,0); ans=(ans*2)%MOD; printf("%lld",ans); return 0;}
70
#include<iostream>#include<cstring>#include<algorithm>#include<cstdio>#include<cmath>#include<queue>#include<vector>#include<climits>#include<string>#include<cstdlib>#include<ctime>#define MOD 1000000007#define MAXN 999999999#define LL long longusing namespace std;LL n,x,num[100005],f[100005],k[100005],p,i,j,tmp,x1,x2,ans,maxn,nnn[100005];LL lowbit(LL emt){ return emt&(-emt);}int main(){ freopen("lowbit.in","r",stdin); freopen("lowbit.out","w",stdout); scanf("%lld",&n); for(i=1;i<=n;i++) { scanf("%lld",&x); nnn[i]=x; maxn=max(maxn,x); if(x<=1024) { num[x]++; if(!f[x]) { f[x]=1; p++; k[p]=x; } } } if(maxn<=1024) { for(i=1;i<p;i++) for(j=i+1;j<=p;j++) { x1=k[i]; x2=k[j]; tmp=2*lowbit(x1^x2)%MOD*(num[x1]%MOD*num[x2]%MOD)%MOD; ans=(ans+tmp)%MOD; } } else { for(i=1;i<=n;i++) for(j=1;j<=n;j++) { tmp=lowbit(nnn[i]^nnn[j])%MOD; ans=(ans+tmp)%MOD; } } printf("%lld",ans); return 0;}
- lowbit
- lowbit
- lowbit
- lowbit
- lowbit
- lowbit
- Lowbit Sum
- Lowbit Sum
- 关于lowbit
- 【lowbit(x)】
- x&(-x) Lowbit(x)
- x&(-x) Lowbit(x)
- ACdream 1154 Lowbit Sum
- poj 2309 BST(lowbit)
- ACdream1154(lowbit的理解)
- 位运算函数lowbit
- 先论lowbit
- lowbit函数 x&(-x)
- 16位汇编下的屏幕截取程序
- 锅打灰太狼游戏
- POJ
- 计算几何--POJ--3304--Segments
- 20170723 做的事 ecdsa的签名验证时间短于bls signature
- lowbit
- 链表面试题之判断链表是否带环?若带环求环的长度?若带环求环的入口点?
- Ubuntu防火墙安装和配置
- pat-a1072. Gas Station (30)
- Zephyr程序初探(1):LED程序及调试过程
- lowbit
- lintcode--单词划分
- 百度2017春招笔试真题编程题集合--寻找三角形
- 欢迎使用CSDN-markdown编辑器