树状数组(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%的,a[i]范围较小,开一个桶数组,记录每个数出现了多少次(因为n<=100000,而a[i]<=1024,每个数一定出现过多次,我们只算一次就行了)

  

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<math.h>
using namespace std;
#define M 1000000007
long long n,c;
int f[];
long long ans,o,maxn;
long long last=,x,y,t;
long long lowbit(long long x)
{
return x&(-x);
}
int main()
{
freopen("lowbit.in","r",stdin);
freopen("lowbit.out","w",stdout);
scanf("%lld",&n);
if(n<=) //这里掉了个等号,调了好久。。。。
{
for(int i=;i<=n;i++)
scanf("%d",&f[i]);
for(int i=;i<=n;i++)
for(int j=i+;j<=n;j++)
o=lowbit((long long)f[i] ^ f[j]),ans=(ans+o)%M;
ans=ans*%M;
cout<<ans;
return ;
}
for(int i=;i<=n;i++)
{
scanf("%lld",&c);
f[c]++;maxn=max(maxn,c);
}
for(int i=;i<=maxn;i++)
for(int j=i+;j<=maxn;j++)
{
t=(i ^ j);
o=lowbit(t);
ans=(ans+o*f[i]*f[j]%M)%M;
}
ans=ans*%M;
cout<<ans;
return ;
}

满分的做法就要考虑lowbit 和二进制数的性质了。

  lowbit是指 某数在二进制中最后一个“1”所在位置的权值。

  两个数 xor(异或)的lowbit与 他们从低位到高位第一个不同位的权值有关。

思路

  (1)那么,我们就从低位向高位注意比较有多少个在这个位上是“1”,多少个是“0”。分别放在集合X,集合Y中。

  (2)那么对于任意a∈X,b∈Y,,    lowbit(a,b)就是这个位的权值。

  这样集合X和Y之间的lowbit就求出来了(集合X,Y内部的数的lowbit还没求),接下来就分别对集合X,Y内部的数,对下一位进行同样操作 (1)(2)

实现的算法可以是分治,也可以是trie树。

  分治做法代码:

  ·

#include<iostream>
#include<queue>
#include<cstdio>
#include<math.h>
#include<algorithm>
using namespace std;
#define M 1000000007
int a[],n;
int b[];
long long ans=,t;
void work(int n,int t)
{
if(n<=||t>) return;
int l=;
for(int i=;i<=n;i++)
if(a[i]&(<<t)) b[++l]=a[i];
int r=l;
for(int i=;i<=n;i++)
if(!(a[i]&(<<t))) b[++r]=a[i];
ans=(ans+(long long)(l*(r-l)*(<<t)%M))%M;
for(int i=;i<=l;i++) a[i]=b[i];
work(l,t+);
for(int i=;i<=r-l;i++) a[i]=b[i+l];
work(r-l,t+);
}
int main()
{
freopen("lowbit.in","r",stdin);
freopen("lowbit.out","w",stdout);
scanf("%d",&n);
for(int i=;i<=n;i++)
scanf("%d",&a[i]);
work(n,);
cout<<ans*%M;
return ;
}

  trie树:

lowbit的更多相关文章

  1. 杂-lowbit

    int lowbit(int x){ )); } int lowbit(int x){ return x&-x; }

  2. #define lowbit(x) ((x)&(-x))原理详解

    #define lowbit(x) ((x)&(-x)) 也可以写成如下形式: int Lowbit(x) { return x&(-x); } 例如: 1> x = 1: 十进 ...

  3. (新人的第一篇博客)树状数组中lowbit(i)=i&(-i) 的简单文字证明

    第一次写博好激动o(≧v≦)o~~初一狗语无伦次还请多多指教   先了解树状数组http://blog.csdn.net/int64ago/article/details/7429868感觉这个前辈写 ...

  4. [USACO 1.5.4]checker(水题重做——位运算(lowbit的应用))

    描述 检查一个如下的6 x 6的跳棋棋盘,有六个棋子被放置在棋盘上,使得每行.每列有且只有一个,每条对角线(包括两条主对角线的所有平行线)上至多有一个棋子. 0 1 2 3 4 5 6 ------- ...

  5. ACdreamOJ 1154 Lowbit Sum (数字dp)

    ACdreamOJ 1154 Lowbit Sum (数位dp) ACM 题目地址:pid=1154" target="_blank" style="color ...

  6. acdream 1154 Lowbit Sum

    先贴代码,以后再写题解... 首先,直接枚举肯定是会超时的,毕竟n就有10^9那么多... 对于每个数,我们先把它转化为二进制:例:21-->10101: 对于00001~10101,可以分为几 ...

  7. poj 2309 BST 使用树阵lowbit

    假设领悟了树阵lowbit,这个问题很简单,底部是奇数,使用lowbit(x)寻找x父亲,然后x父亲-1是的最大数量 至于lowbit问题是如何计算,寻找x父亲,事实上x+2^x二进制结束0的数量. ...

  8. hdu_5618_Jam's problem again(cdq分治+lowbit)

    题目链接:hdu_5618_Jam's problem again 题意: 给你n个点,每个点有一个坐标(x,y,z),找出有ans个点,3个坐标都比该点小,这个点的level就为ans,然后让你输出 ...

  9. 树状数组lowbit()函数原理的解释 x&(x^(x-1)) x&-x

    树状数组lowbit()函数所求的就是最低位1的位置所以可以通过位运算来计算 树状数组通过 x&(x^(x-1)) 能够成功求出lowbit的原因: 首先设x=6,即110(2) 于是我们使 ...

  10. Lowbit Sum 规律

    Lowbit Sum Time Limit: 2000/1000MS (Java/Others) Memory Limit: 128000/64000KB (Java/Others) SubmitSt ...

随机推荐

  1. 对Webview跨源攻击的理解

    首先是addJavaScriptInterface漏洞: 有时候访问手机百度贴吧网页版本,网页上会有个按钮提示用手机应用打开.这种交互通常都是使用JS来实现,而WebView已经提供了这样的方法,具体 ...

  2. Tensorflow基础知识

    基本知识 使用 TensorFlow, 你必须明白 TensorFlow: 使用图 (graph) 来表示计算任务. 在被称之为 会话 (Session) 的上下文 (context) 中执行图. 使 ...

  3. pytest用例setup和teardown

    函数式以下两种: setup_function/teardown_function  每个用例开始和结束调用一次 setup_module/teardown_module     setup_modu ...

  4. PTA-数据结构 Dijkstra 城市间紧急救援

    城市间紧急救援(25 分) 作为一个城市的应急救援队伍的负责人,你有一张特殊的全国地图.在地图上显示有多个分散的城市和一些连接城市的快速道路.每个城市的救援队数量和每一条连接两个城市的快速道路长度都标 ...

  5. saltstack api安装使用

    Salt自然也是提供api的,使用api对自动化有极大的帮助,我们使用rest风格的api,当然大家都知道salt是python写的,那么自然也就提供了对应的api,但是并不建议使用,因为调用pyth ...

  6. python在三引号中使用变量

  7. Alien Flowers

    题意: 求含有A个"RR",B个"RB",C个"BB",D个"BR"的字符串个数. 解法: 首先考虑"BR&q ...

  8. 挨踢职场求生法则-----我在IT职场打滚超过15年了,从小小的程序员做到常务副总

    摘要我在IT职场打滚超过15年了,从小小的程序员做到常务副总.相对于其它行业,IT职场应该算比较光明的了,但也陷阱重重,本文说说我的亲身体会,希望大家能在IT职场上战无不胜! 通用法则 法则1:忍耐是 ...

  9. DOM学习笔记(二)对象方法与属性

    所有 HTML 元素被定义为对象,而编程接口(对象的访问)则是对象方法和对象属性. 事实上,常用的只用window对象及其子对象document对象,以及事件Event对象. Window 对象 Wi ...

  10. E20180511-hm

    thread  n. 螺纹; 线; 线索; 线状物;      vt. 穿成串; 将(针.线等)穿过…; 用…线缝; 给…装入(胶片.狭带.绳子); needle n. 针; 针状物; <口&g ...