HDU 5269 ZYB loves Xor I

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5269


题意:给n个数,求所有的lowbit( a[i] xor a[j] )之和,i,j∈[1,n]
lowbit是一个数在二进制表示下的第一个1所在位的权值。


思路:首先是求所有点对,而且自己和自己算出来是0不用考虑,那么对于一个数,我们就只求这个数到它前面所有点的答案,最后再把答案乘2即可。
我们构建一棵trie树,因为数的范围小于2^29,我们将每一个数固定为30位二进制数插入trie树里面,并统计每个节点的经过次数。


这样,对于一个数x所贡献的答案,我们可以这样计算。枚举它的每一位p,假设存在一个数y,使得lowbit(x xor y) = 2^p ,那么x和y的前p-1位一定是一样的,然后我们查询第p位与x的第p位相异节点的经过次数num,第p位贡献的答案就是num*2^(p-1)


#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>


using namespace std;
#define LL long long
#define rep(i,j,k) for(int i = j; i <= k; i++ )
#define Rrep(i,j,k) for(int i = j; i >= k; i-- )
#define Clean(x,y) memset(x,y,sizeof(x))
#define mod 998244353

int T;
int n;
LL ans;

int len;
int root;
int Next[1000009][2];
int num[1000009];

void init()
{
    root = 0;
    len = 0;
    Clean(Next,0);
    Clean(num,0);
}

void insert(int root,int k)
{
    int now = root;
    rep(i,0,29)
    {
        int index = k & 1;
        if ( !Next[now][index] ) Next[now][index] = ++len;
        now = Next[now][index];
        num[now]++;
        k>>=1;
    }
}

int query(int root,int k)
{
    int now = root;
    int temp;
    int ans = 0;
    int value = 1; //对应每一位上的权值
    rep(i,0,29) //枚举每一位
    {
        temp = k & 1;
        ans += value * num[Next[now][ 1 - temp ]]; //走与当前位相异的那个点计算答案
        if ( Next[now][temp] == 0 ) break;
        now = Next[now][temp];
        value<<=1;
        k>>=1; 
    }
    return ans;
}


int main()
{
    int temp;
    cin>>T;
    int kase = 0;
    while(T--)
    {
        cin>>n;
        ans = 0;
        init();
        while(n--)
        {
            scanf("%d",&temp);
            insert(root,temp);
            ans+=query(root,temp);
        }
        printf("Case #%d: ",++kase);
        cout<<ans*2%mod<<endl;
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值