题意:给出一列数,求任意两个数的异或值得lowbit值和。PS:一个数的lowbit为,第一个不为0的数前有k个0,则为2^k。
题解:利用字典树存储这些数的二进制,每次插入将相应的异或的lowbit加入ans里面(其实就是简单的排列组合)
AC代码:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn=2e6+5;
const ll mod = 998244353;
ll son[maxn][3],sum[maxn],idx;
ll bit[35],ans;
void init(){
memset(son,-1,sizeof(son));
memset(sum,0,sizeof(sum));
idx=0,ans=0;
}
void insert(ll x){
int root=0;
for(int i=0;i<=30;i++){
int v=x&(1<<i)?1:0;//获取x的二进制第i位,这里必须这样判断,得到0说明这一位是0,否者大于零就是1
if(son[root][v]==-1)son[root][v]=++idx;//不存在就创建结点
if(son[root][1^v]!=-1)//存在这一位与v相异的数
ans=(ans+bit[i]*sum[son[root][1^v]]%mod)%mod;
root=son[root][v];
sum[root]+=1;//当前结点分叉+1
}
}
int main(){
int t,kase=1,n;
cin>>t;
bit[0]=1;
for(int i=1;i<=30;i++)bit[i]=bit[i-1]*2;
while(t--){
cin>>n;
init();
for(int i=1;i<=n;i++){
ll x;
cin>>x;
insert(x);
}
ans=(ans*2)%mod;
printf("Case #%d: %lld\n",kase++,ans);
}
}
标签:HDU,01,Xor,int,ll,son,ans,root,sum From: https://blog.51cto.com/u_15958888/6044777