标签:
题目链接:传送门
题意:
求
for i: 1~n forj:1~n lowbit(a[i]^a[j]) lowbit(x)表示取x的最低位1。
lowbit(3)=1 lowbit(6)=2;
分析:
因为其中有一个异或运算,我们就先来分析这个异或运算。发现如果lowbit(x^y) = 2^p;
那么把x^y转化成2进制后他们的前p-1位一定是相同的。那么思路就来了把所有的数字转换
成01字符串,注意要使他们的长度都相等,然后建一颗trie树。然后遍历的时候如果同时
有左右孩子的话那么ans = ans(ans + l_num*r_num)%mod;最后的ans还要乘以2.
代码如下:
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <set> #include <map> #include <queue> #define PB push_back #define MP make_pair #define REP(i,n) for(int i=0;i<(n);++i) #define FOR(i,l,h) for(int i=(l);i<=(h);++i) #define DWN(i,h,l) for(int i=(h);i>=(l);--i) #define IFOR(i,h,l,v) for(int i=(h);i<=(l);i+=(v)) #define CLR(vis) memset(vis,0,sizeof(vis)) #define MST(vis,pos) memset(vis,pos,sizeof(vis)) #define MAX3(a,b,c) max(a,max(b,c)) #define MAX4(a,b,c,d) max(max(a,b),max(c,d)) #define MIN3(a,b,c) min(a,min(b,c)) #define MIN4(a,b,c,d) min(min(a,b),min(c,d)) #define PI acos(-1.0) #define INF 1000000000 #define LINF 1000000000000000000LL #define eps 1e-8 #define LL long long using namespace std; const LL mod = 998244353; const int maxn =5e4+10; LL a[maxn]; const int max_size = 2; int id(char c){ return c-'0'; } struct Trie{ Trie *ch[2]; LL num; Trie(){ num = 0; for(int i=0;i<max_size;i++) ch[i]=NULL; } }; void insert_str(Trie *root,char *s){ Trie *p = root; for(int i=0; p&&s[i] ; i++){ int u = id(s[i]); if(p->ch[u]==NULL) p->ch[u] = new Trie; p=p->ch[u]; p->num++; //cout<<"***"<<p->num<<endl; } } LL ans; void dfs(Trie *ff,LL dept){ Trie *p = ff; if(p->ch[0]!=NULL&&p->ch[1]!=NULL){ ans=(ans+(p->ch[0]->num*p->ch[1]->num)%mod*((1LL<<dept)%mod))%mod; } if(p->ch[0]!=NULL) dfs(p->ch[0],dept+1); if(p->ch[1]!=NULL) dfs(p->ch[1],dept+1); return ; } inline LL read() { LL x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } int main() { LL n,t; int cas=1; t=read(); char s[50]; while(t--){ Trie *root = new Trie; n=read(); REP(i,n) a[i]=read(); ans = 0; REP(i,n){ int cnt = 0; LL tmp =a[i]; while(tmp){ s[cnt++]=tmp%2+'0'; tmp/=2; } FOR(i,cnt,40) s[i]='0'; s[41]=0; insert_str(root,s); } dfs(root,0); printf("Case #%d: %I64d\n",cas++,(ans<<1)%mod); } return 0; }
HDU 5269 ZYB loves Xor I( 01 Trie 树)
标签:
原文地址:http://blog.csdn.net/bigbigship/article/details/46489383