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%的,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的更多相关文章
- 杂-lowbit
int lowbit(int x){ )); } int lowbit(int x){ return x&-x; }
- #define lowbit(x) ((x)&(-x))原理详解
#define lowbit(x) ((x)&(-x)) 也可以写成如下形式: int Lowbit(x) { return x&(-x); } 例如: 1> x = 1: 十进 ...
- (新人的第一篇博客)树状数组中lowbit(i)=i&(-i) 的简单文字证明
第一次写博好激动o(≧v≦)o~~初一狗语无伦次还请多多指教 先了解树状数组http://blog.csdn.net/int64ago/article/details/7429868感觉这个前辈写 ...
- [USACO 1.5.4]checker(水题重做——位运算(lowbit的应用))
描述 检查一个如下的6 x 6的跳棋棋盘,有六个棋子被放置在棋盘上,使得每行.每列有且只有一个,每条对角线(包括两条主对角线的所有平行线)上至多有一个棋子. 0 1 2 3 4 5 6 ------- ...
- ACdreamOJ 1154 Lowbit Sum (数字dp)
ACdreamOJ 1154 Lowbit Sum (数位dp) ACM 题目地址:pid=1154" target="_blank" style="color ...
- acdream 1154 Lowbit Sum
先贴代码,以后再写题解... 首先,直接枚举肯定是会超时的,毕竟n就有10^9那么多... 对于每个数,我们先把它转化为二进制:例:21-->10101: 对于00001~10101,可以分为几 ...
- poj 2309 BST 使用树阵lowbit
假设领悟了树阵lowbit,这个问题很简单,底部是奇数,使用lowbit(x)寻找x父亲,然后x父亲-1是的最大数量 至于lowbit问题是如何计算,寻找x父亲,事实上x+2^x二进制结束0的数量. ...
- hdu_5618_Jam's problem again(cdq分治+lowbit)
题目链接:hdu_5618_Jam's problem again 题意: 给你n个点,每个点有一个坐标(x,y,z),找出有ans个点,3个坐标都比该点小,这个点的level就为ans,然后让你输出 ...
- 树状数组lowbit()函数原理的解释 x&(x^(x-1)) x&-x
树状数组lowbit()函数所求的就是最低位1的位置所以可以通过位运算来计算 树状数组通过 x&(x^(x-1)) 能够成功求出lowbit的原因: 首先设x=6,即110(2) 于是我们使 ...
- Lowbit Sum 规律
Lowbit Sum Time Limit: 2000/1000MS (Java/Others) Memory Limit: 128000/64000KB (Java/Others) SubmitSt ...
随机推荐
- UVA-10534 (LIS)
题意: 给定一个长为n的序列,求一个最长子序列,使得该序列的长度为2*k+1,前k+1个数严格递增,后k+1个数严格单调递减; 思路: 可以先求该序列最长单调递增和方向单调递增的最长序列,然后枚举那第 ...
- 【C】貌似不友好的scanf()
scanf语句执行过程: (1)逆序取参数的偏移地址并分别入栈. (2)根据控制字符串的格式说明符从缓冲区取数据给各变量赋值. ①若格式说明符是数值类数据:如果从缓冲区中拿出的第一个字符可以合法表示该 ...
- Fire Game
Description Fat brother and Maze are playing a kind of special (hentai) game on an N*M board (N rows ...
- React-Native 基本环境的搭建
看了一些RN资料,仅仅了解到人们对 RN(以下简称 React_native 框架) 的使用描述以及评价,就觉得RN是一个很不错的框架,值得学习.今天就开始写我的学习记录,也给大家分享一下.下面进入正 ...
- P-Function
题意: 对于集合 $S = {1, 2, ...., n}$ , 定义函数 $F(x) = y, x, y$ 属于 $S$,对于任何 $x$ 属于 $S$, 有 $F(F...F(x)) = x$, ...
- Count Subsets
题意: 给一集合 $S = \{ 1,2, ... , n \} $,取两个S的子集 A和B,使得A不是B的子集,且B不是A的子集. 解法: 1.牛顿展开 我们采用容斥,显然有 $$ans(n) = ...
- XML DOM 笔记
一.概念理解: 关于Element跟Node的区别,cilldren跟childNodes的区别很多朋友弄不清楚,本文试图让大家明白这几个概念之间的区别. Node(节点)是DOM层次结构中的任何类型 ...
- T^TOJ - 2360 - Home_W的超级数学题 - 莫比乌斯反演 - 质因数分解
求单个莫比乌斯函数忘记算n本身的质数,WA了一发. http://www.fjutacm.com/Problem.jsp?pid=2360 首先,显然随着n增大,与m互质的数不会变少.可以二分来求k, ...
- C++构造函数和拷贝构造函数详解
构造函数.析构函数与赋值函数是每个类最基本的函数.它们太普通以致让人容易麻痹大意,其实这些貌似简单的函数就象没有顶盖的下水道那样危险. 每个类只有一个析构函数和一个赋值函数,但可以有多个构造函数(包含 ...
- lightoj 1085【离散化+树状数组】
题意: 求所有的上升子序列种数: 思路: 我想先离散化一下,然后用树状数组维护一下. 最终答案就是sum(n) ? 卧槽,好像是:然后就过了.. #include <bits/stdc++.h& ...