HDU 5269 ZYB loves Xor I

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

题意:给定n个数,求所有(lowbit(Ai ^ Aj)) (i,j[1,n])(i,j∈[1,n]) 的和

 

因为要求lowbit 所以字典树插入时应该从最低位开始

在插入时,与当前位不同的位置如果已经有数了

那么答案就该加上(1<<i)*val[ch[now][t^1]]

因为 i 和 j 可以对调,所以最终答案还要乘2

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
using namespace std;
const int mod=998244353;
const int N=5e4+5;
int a[N];
int ans;
struct trie
{
    int tot;
    int ch[30*N][2],val[30*N];
    void init()
    {
        tot=0;
        memset(ch[tot],0,sizeof(ch[tot]));
        memset(val,0,sizeof(val));
    }
    void add(int x,int y)
    {
        int now=0;
        for(int i=0;i<30;i++)
        {
            int t=x>>i&1;
            if (!ch[now][t])
            {
                ch[now][t]=++tot;
                memset(ch[tot],0,sizeof(ch[tot]));
            }
            if (ch[now][t^1])
                ans=(ans+1LL*(1<<i)*val[ch[now][t^1]]%mod)%mod;
            now=ch[now][t];
            val[now]+=y;
        }
    }
}tree;

int main()
{
    int T;
    scanf("%d",&T);
    for(int ca=1;ca<=T;ca++)
    {
        int n;
        scanf("%d",&n);
        tree.init();
        ans=0;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            tree.add(a[i],1);
        }
        ans=(ans<<1)%mod;
        printf("Case #%d: %d\n",ca,ans);
    }
    return 0;
}

  

posted @ 2017-09-11 13:15  BK_201  阅读(162)  评论(0编辑  收藏  举报