题解:P11209 『STA - R8』小熊游景点 II
题意:
给定长度为
一共
题解:
对于异或问题,考虑字典树。
我们把关于
从高到低枚举位,
- 前
j-1 位都一样,并且第j 位的b_i 是1
我们发现只要
但是还要考虑如果这位的
- 前
j-1 位都一样,并且第j 位的b_i 位是0
那么此时只有当异或值位
并且我们需要对最后移位特判,因为等于这种情况也是可行的。
对于查询只需要按照
当 a_i=0111 和 b_i=0101 时举个例子。
-
对于最高位,只有
k 这位等于0 才可能产生贡献,所以只建立一个0 的节点。 -
对于第二位,当
k 这位等于1 时一定可行,所以在1 那里+1 。当k 这位等于0 时也可能可行,所以也要建立一个节点。 -
对于第三位,只有
k 这位等于1 时可能可行,所以往1 建立节点。 -
对于最后一位,我们发现
k 这位等于0 或1 都能产生贡献,所以都打一个+1 的标记。
当
当
当
复杂度:
建立节点时我们最多只会往一边去建立节点,所以是
code:
#include<bits/stdc++.h>
using namespace std;
int tot;
int a[500010],b[500010];
struct Tree{
int ch[2],val;
Tree(){
memset(ch,0,sizeof(ch));
}
}tr[16000010];
int f=0;
void insert(int x,int y){
int p=0;
for(int i=31;i>=0;i--){
int k1=(x>>i)&1,k2=(y>>i)&1,q;
if(i==0){
if(k2==0){
q=k1;
if(tr[p].ch[q]==0)
tr[p].ch[q]=++tot;
tr[tr[p].ch[q]].val++;
}else{
q=k1;
if(tr[p].ch[q]==0)
tr[p].ch[q]=++tot;
tr[tr[p].ch[q]].val++;
q=k1^1;
if(tr[p].ch[q]==0)
tr[p].ch[q]=++tot;
tr[tr[p].ch[q]].val++;
}
continue;
}
if(k2==1){
q=k1;
if(tr[p].ch[q]==0)
tr[p].ch[q]=++tot;
tr[tr[p].ch[q]].val++;
q=k1^1;
if(tr[p].ch[q]==0)
tr[p].ch[q]=++tot;
p=tr[p].ch[q];
}else{
q=k1;
if(tr[p].ch[q]==0)
tr[p].ch[q]=++tot;
p=tr[p].ch[q];
}
}
}
int query(int x){
int p=0,ans=0;
for(int i=31;i>=0;i--){
int q=(x>>i)&1;
if(tr[p].ch[q])ans+=tr[tr[p].ch[q]].val,p=tr[p].ch[q];
else break;
}
return ans;
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int T,n,q;
cin>>T>>n>>q;
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=1;i<=n;i++)cin>>b[i],insert(a[i],b[i]);
int lst=0;
while(q--){
int k;
cin>>k;
k=k^(lst*T);
lst=query(k);
cout<<lst<<'\n';
}
return 0;
}