题目: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 ",ca,ans); } return 0; }