Bitwise Xor
Zhong Ziqian got an integer array (a_1, a_2, ldots, a_n) and an integer (x) as birthday presents.
Every day after that, he tried to find a non-empty subsequence of this array (1 leq b_1 < b_2 < ldots < b_k leq n), such that for all pairs ((i, j)) where (1 leq i < j leq k), the inequality (a_{b_i} oplus a_{b_j} geq x) held. Here, (oplus) is the bitwise exclusive-or operation.
Of course, every day he must find a different subsequence.
How many days can he do this without repeating himself? As this number may be very large, output it modulo (998\,244\,353).
(1 leq n leq 300\,000, 0 leq x leq 2^{60}-1)
题解
https://drive.google.com/file/d/1BuDTosfabqMZGEu2zyqTmkS2QsIYWsG6/view
若干个数两两异或的最小值必在排序后相邻两个取到。排序后直接用Trie优化DP即可。
具体而言,用f[i]
表示以第i
个数结尾的子序列个数。在Trie中查询更新,然后把它插入到Trie中。
时间复杂度 (O(n log x))。
CO int N=3e5+10;
int64 a[N];
int ch[N*61][2],sum[N*61],tot=1;
void insert(int x,int64 p,int d,int v){
sum[x]=add(sum[x],v);
if(d==-1) return;
int c=p>>d&1;
if(!ch[x][c]) ch[x][c]=++tot;
insert(ch[x][c],p,d-1,v);
}
int query(int x,int64 l,int64 r,int d){
if(!x) return 0;
if(d==-1) return sum[x];
if(r>>d&1){
if(l>>d&1) return query(ch[x][0],l,r,d-1);
else return query(ch[x][1],l,r,d-1);
}
else{
if(l>>d&1) return add(sum[ch[x][0]],query(ch[x][1],l,r,d-1));
else return add(query(ch[x][0],l,r,d-1),sum[ch[x][1]]);
}
}
int main(){
int n=read<int>();
int64 X=read<int64>();
for(int i=1;i<=n;++i) read(a[i]);
sort(a+1,a+n+1);
int ans=0;
for(int i=1;i<=n;++i){
int f=add(1,query(1,a[i],X,60));
ans=add(ans,f);
insert(1,a[i],60,f);
}
printf("%d
",ans);
return 0;
}