lowbit

来源:互联网 发布:网络共享打不开 编辑:程序博客网 时间:2024/05/12 12:45

树状数组(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。

这个题可以分治,把奇数和偶数分成两堆,然后就AC
思想就是转成二进制,然后异或,如果最末位相同,就向前搜寻,需要注意ans要开long long
(开了long long也不行),计算的时候也有可能会爆掉,有一种操作是1ll*(……)类似于强制转换
然后就可以轻松AC

#include <iostream>#include <cstdio>#define P 1000000007using namespace std;int a[111111],b[111111];long long ans;void work(int p,int u){    if(p<=1||u>=30)        return ;    int l=0;    for(int i=1;i<=p;i++)        if(a[i]&(1<<u)) b[++l]=a[i];    int r=l;    for(int i=1;i<=p;i++)        if(!(a[i]&(1<<u)))  b[++r]=a[i];    for(int i=1;i<=p;i++)   a[i]=b[i];    ans+=((1ll*(1<<u))%P*l)%P*(p-l)%P;    work(l,u+1);     int q=0;    for (int i=l+1;i<=r;i++) a[++q]=a[i];    work(q,u+1);}int main(){    freopen("lowbit.in","r",stdin);    freopen("lowbit.out","w",stdout);    int n;    cin>>n;    for(int i=1;i<=n;i++)    {        cin>>a[i];    }    work(n,0);    printf("%lld",ans*2%P);    return 0;}
原创粉丝点击