分治法和字典树都可以,都是递归,但字典树耗内存
从第一bit开始,若相同则xor为0,分到同一部分,不相同则统计,且此时lowbit为这一bit,最后结果要乘以2
1 /*分治法*/ 2 #include<cstdio> 3 #define MOD 998244353 4 5 using namespace std; 6 7 int a[50010],t[50010],T,cas=1,n,sum; 8 9 void fenzhi(int l,int r,int mask) 10 { 11 if(r-l<=1||mask==1<<30) return; 12 int i,j=l,k=r-1; 13 for(i=l;i<r;i++) 14 { 15 if(a[i]&mask) t[j++]=a[i]; 16 else t[k--]=a[i]; 17 } 18 sum=(sum+(long long)(j-l)*(r-j)*mask)%MOD; 19 for(i=l;i<r;i++) a[i]=t[i]; 20 fenzhi(l,j,mask<<1); 21 fenzhi(j,r,mask<<1); 22 } 23 int main() 24 { 25 scanf("%d",&T); 26 while(T--) 27 { 28 scanf("%d",&n); 29 for(int i=0;i<n;i++) 30 scanf("%d",&a[i]); 31 sum=0; 32 fenzhi(0,n,1); 33 printf("Case #%d: %d\n",cas++,(sum*2)%MOD); 34 } 35 return 0; 36 }
1 /*字典树*/ 2 #include <iostream> 3 #include<cstdio> 4 #include<cstring> 5 #define MOD 998244353 6 7 using namespace std; 8 9 struct Node 10 { 11 int num; 12 int left,right; 13 }; 14 Node node[1600010]; 15 int T,n,a,idx,sum,cas=1; 16 17 void insert(int a) 18 { 19 int root=1,mask=1; 20 for(int i=0;i<30;i++) 21 { 22 if(a&mask) 23 { 24 int &u=node[root].left; 25 if(!u) u=idx++; 26 node[u].num++; 27 root=u; 28 } 29 else 30 { 31 int&u=node[root].right; 32 if(!u) u=idx++; 33 node[u].num++; 34 root=u; 35 } 36 mask<<=1; 37 } 38 } 39 40 void dfs(int x,int depth) 41 { 42 if(node[x].num<=1) return; 43 sum=(sum+(long long)node[node[x].left].num*node[node[x].right].num*(1<<depth))%MOD; 44 dfs(node[x].left,depth+1); 45 dfs(node[x].right,depth+1); 46 } 47 int main() 48 { 49 scanf("%d",&T); 50 while(T--) 51 { 52 scanf("%d",&n); 53 memset(node,0,sizeof(node[0])*n*30); 54 idx=2; 55 node[1].num=n; 56 for(int i=0;i<n;i++) 57 { 58 scanf("%d",&a); 59 insert(a); 60 } 61 sum=0; 62 dfs(1,0); 63 printf("Case #%d: %d\n",cas++,sum*2%MOD); 64 } 65 return 0; 66 }
时间: 2024-10-12 21:15:36