[石油大OJ] 腿部挂件

mac2025-12-05  11

题目描述:

给出 N 个数 M个询问 每次询问给出 L R X 三个参量 询问从L-R中的数字与X最大的异或值是多少

题目分析:

异或最大值问题应该是用 01 字典树来做 然后关于区间直接像主席树那样搞个可持久化就OK了

AC代码:

#include <cstdio> #include <iostream> #include <algorithm> const int maxn=210000,maxm=210000*30; int _div[40],root[maxn],sz; int n,m,q; struct tree{ int son[maxm][2],sum[maxm]; void insert(int num,int &now,int pre) { now=++sz; son[now][0]=son[pre][0]; son[now][1]=son[pre][1]; sum[now]=sum[pre]+1; if(!num) return; insert(num-1,son[now][_div[num-1]],son[pre][_div[num-1]]); } int ask(int num,int now,int pre) { if(!num) return 0; if(sum[son[now][_div[num-1]]]>sum[son[pre][_div[num-1]]]) return ask(num-1,son[now][_div[num-1]],son[pre][_div[num-1]])+(1<<(num-1)); else return ask(num-1,son[now][!_div[num-1]],son[pre][!_div[num-1]]); } }st; int main() { scanf("%d%d",&n,&m); for(int i=1,x;i<=n;i++) { scanf("%d",&x); for(int j=0;j<30;j++,x/=2) _div[j]=x%2; st.insert(30,root[i],root[i-1]); } for(int i=1,l,r,x;i<=m;i++) { scanf("%d%d%d",&x,&l,&r); for(int j=0;j<30;j++,x/=2) _div[j]=1-x%2; printf("%d\n",st.ask(30,root[r+1],root[l])); } return 0; }
最新回复(0)