hdu5269 ZYB loves Xor I 异或,字典树

hdu5269  ZYB loves Xor I   异或,字典树

ZYB loves Xor I

 
 Accepts: 142
 
 Submissions: 696
 Time Limit: 2000/1000 MS (Java/Others)
 
 Memory Limit: 65536/65536 K (Java/Others)
问题描述
ZYB喜欢研究Xor,现在他得到了一个长度为nn的数组A。于是他想知道:对于所有数对(i,j)(i \in [1,n],j \in [1,n])(i,j)(i[1,n],j[1,n]),lowbit(A_i xor A_j)lowbit(Ai​​xorAj​​)之和为多少.由于答案可能过大,你需要输出答案对998244353取模后的值
定义lowbit(x)=2^k2k​​,其中k是最小的满足(xx andand 2^k)>02k​​)>0的数
特别地:lowbit(0)=0
输入描述
一共TT(T \leq 10T10)组数据,对于每组数据:
第一行一个正整数nn,表示数组长度
第二行nn个非负整数,第ii个整数为A_{i}Ai​​
n \in [1,5*10^4]n[1,5104​​],A_i \in [0,2^{29}]Ai​​[0,229​​]
输出描述
每组数据输出一行Case #x: ans。x表示组数编号,从1开始。ans为所求值。
输入样例
2
5
4 0 2 7 0
5
2 6 5 4 0
输出样例
Case #1: 36
Case #2: 40

之前一直没能过这题,现在看来就很简单了,以后看到异或也自然而然地想到字典树。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#define REP(i,a,b) for(int i=a;i<=b;i++)
#define MS0(a) memset(a,0,sizeof(a))

using namespace std;

typedef long long ll;
const int maxn=1000100;
const int INF=(1<<29);
const ll MOD=998244353;

struct Trie
{
    int ch[2];
    int siz;
};Trie tr[maxn];int p;int rt;
int n,a[maxn];

int newnode()
{
    tr[++p].siz=0;
    tr[p].ch[0]=tr[p].ch[1]=-1;
    return p;
}

void Init()
{
    p=-1;
    rt=newnode();
}

void Insert(int t)
{
    int k=rt;
    int c=0;
    tr[k].siz++;
    REP(i,0,30){
        if(t&(1<<i)) c=1;
        else c=0;
        if(tr[k].ch[c]==-1) tr[k].ch[c]=newnode();
        k=tr[k].ch[c];
        tr[k].siz++;
    }
}

ll query(int t)
{
    int k=rt;
    int c;
    ll res=0;
    REP(i,0,30){
        if(t&(1<<i)) c=1;
        else c=0;
        if(~tr[k].ch[c^1]) res+=tr[tr[k].ch[c^1]].siz*(1<<i)%MOD;
        if(tr[k].ch[c]==-1) break;
        k=tr[k].ch[c];
    }
    return res%MOD;
}

int main()
{
    freopen("in.txt","r",stdin);
    int casen=1;
    int T;cin>>T;
    while(T--){
        scanf("%d",&n);
        Init();
        REP(i,1,n){
            scanf("%d",&a[i]);
            Insert(a[i]);
        }
        ll ans=0;
        REP(i,1,n) ans+=query(a[i]),ans%=MOD;
        printf("Case #%d: %I64d\n",casen++,ans);
    }
    return 0;
}
View Code

 

posted @ 2015-11-04 23:00  __560  阅读(320)  评论(0编辑  收藏  举报