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。

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

#include <iostream>
#include <cstdio>
#define P 1000000007
using 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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值