lowbit
来源:互联网 发布:mac install ipython 编辑:程序博客网 时间:2024/05/21 10:52
话说这道题跟lowbit确实没有啥关系
树状数组(lowbit)
Time Limit:1000ms Memory Limit:128MB
题目描述
这天,LYK在学习树状数组。
当它遇到一个叫lowbit的函数时有点懵逼。lowbit(x)的意思是将x分解成二进制,它的值就是,其中k是最小的满足(x & )>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。
首先是70的做法
前面30的数据直接暴力过
后40 ai<1024,我们用一个sum数组记录0-1024这些数出现的次数,然后,枚举数字这样就是1024^2可以过啦
#include <cstdio>#include <iostream>using namespace std;int sum[2000];int a[100011];const int mod=1000000007;int main(){ freopen("lowbit.in","r",stdin); freopen("lowbit.out","w",stdout); int maxf=-1e5; int n; scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]),maxf=max(maxf,a[i]); if(maxf<=1024) { for(int i=1;i<=n;i++) sum[a[i]]++; long long ans=0; for(int i=0;i<=maxf;i++) for(int j=i+1;j<=maxf;j++) { int tmp=(i^j); tmp=(tmp&-tmp); ans=(ans+1ll*tmp*sum[i]*sum[j])%mod; } printf("%lld",ans*2%mod); } else { long long ans=0; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { int w=a[i]^a[j]; if(j!=i) ans=(ans+(w&-w))%mod; } printf("%lld",ans%mod); } return 0;}
讲一下正解
lowbit(x,y),把x、y都分解成二进制,奇数二进制末位是1,偶数是0。
若要lowbit(x^y)=1,则需要末位不相同,即要求一个奇数和一个偶数搭配。
我们把所有的奇数归到一类放在左边,假设有x个;把所有的偶数放到右边,假设有y个。
则一共有xy2对lowbit(x,y)=1,贡献值为x*y2*1;
若要lowbit
(x^y)=2,则需要末位x和y全奇,或者全偶。并且倒数第二位两者不相同。
即在已经看过第一位的时候,再分别看末位为0和末位为1的两组(即奇数和偶数),
在其中的一组中,再次把他们分成倒数第二位为0,倒数第二位为奇的两组(即奇数和偶数)。
假设此时倒数第一位全是奇数的条件下,倒数第二位奇数有a个,偶数有b个,
则它的贡献为a*b2*2(末位为偶数也是这样)。
如果在要
lowbit(x^y)=4,则要在末位,倒数第二位相同的的情况下,在进行细分。
这样,一个分治的思路就体现出来了。
分治完之后, 二元组一个在左边,另一个在右边,这样的贡献是很容易统计的。
对于每一个数,它只在最多31层中被分治到,总时间复杂度是n*31。
对于每一个数ai,我们求出有多少aj,
使得lowbit(ai^aj)=1
lowbit(ai^aj)=2
。。。。。。。
lowbit(ai^aj)=2^29
#include <cstdio>#include <iostream>using namespace std;const int mod=1000000007;int n;int a[100010];int b[100010];long long ans;void dfs(int n,int t){ if(n<=1||t>29) return; int l=0; for(int i=1;i<=n;i++) if(a[i]&(1<<t)) b[++l]=a[i]; int r=l; for(int i=1;i<=n;i++) if(!(a[i]&(1<<t))) b[++r]=a[i]; for(int i=1;i<=n;i++) a[i]=b[i]; ans=(ans+(1ll*(1<<t)*(n-l)*l)%mod)%mod; dfs(l,t+1); int cnt=0; for(int i=l+1;i<=r;i++) a[++cnt]=b[i]; dfs(cnt,t+1);}int main(){ //freopen("lowbit.in","r",stdin); //freopen("lowbit.out","w",stdout); scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); dfs(n,0); printf("%lld",ans*2%mod); fclose(stdin); fclose(stdout); 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)
- mysql常用操作汇总(五)
- 如何使用Moco模拟HTTP网络接口
- HDU 1072 Nightmare
- Java 基础(一)
- div#sidebar{}与#sidebar div{}的区别
- lowbit
- mysql恢复之delete 忘加where条件误删除恢复(binglog格式必须是ROW)
- 现有一块草坪,长为20米,宽为2米,要在横中心线上放置半径为Ri的喷水装置,每个喷水装置的效果都会让以它为中心的半径为实数Ri(0<Ri<15)的圆被湿润,这有充足的喷水装置i(1<i<600)个,并
- Day2
- 大理石在哪儿 (排序和查找) UVA
- centOS6.8升级gcc
- 《深入理解Java虚拟机》读书笔记(2)---第3章 垃圾收集器与内存分配策略(一)
- Goole C++ 单元测试框架(一)
- Java GC与内存分配策略