一家餐厅有 n 道菜,编号 1...n ,大家对第 i 道菜的评价值为 ai(1≤i≤n)。有 m 位顾客,第 i 位顾客的期
望值为 bi,而他的偏好值为 xi 。因此,第 i 位顾客认为第 j 道菜的美味度为 bi XOR (aj+xi),XOR 表示异或
运算。第 i 位顾客希望从这些菜中挑出他认为最美味的菜,即美味值最大的菜,但由于价格等因素,他只能从第
li 道到第 ri 道中选择。请你帮助他们找出最美味的菜。
输出 m 行,每行 1 个整数,ymax ,表示该位顾客选择的最美味的菜的美味值。
#include<set> #include<map> #include<queue> #include<stack> #include<cmath> #include<cstdio> #include<vector> #include<cstring> #include<iostream> #include<algorithm> using namespace std; int n,m; int l,r; int cnt; int ans; int maxv; int a,b,x; int ls[4000010]; int rs[4000010]; int sum[4000010]; int root[200010]; int updata(int pre,int l,int r,int v) { int rt=++cnt; if(l==r) { sum[rt]=sum[pre]+1; return rt; } ls[rt]=ls[pre]; rs[rt]=rs[pre]; sum[rt]=sum[pre]+1; int mid=(l+r)>>1; if(v<=mid) { ls[rt]=updata(ls[pre],l,mid,v); } else { rs[rt]=updata(rs[pre],mid+1,r,v); } return rt; } int query(int x,int y,int l,int r,int L,int R) { if(L<=l&&r<=R) { return sum[y]-sum[x]; } int mid=(l+r)>>1; if(L>mid) { return query(rs[x],rs[y],mid+1,r,L,R); } else if(R<=mid) { return query(ls[x],ls[y],l,mid,L,R); } else { return query(ls[x],ls[y],l,mid,L,R)+query(rs[x],rs[y],mid+1,r,L,R); } } bool find(int l,int r,int L,int R) { L=max(0,L); R=min(maxv,R); if(L>R) { return 0; } else { return query(root[l],root[r],0,1<<18,L,R); } } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { scanf("%d",&a); maxv=max(a,maxv); root[i]=updata(root[i-1],0,1<<18,a); } for(int j=1;j<=m;j++) { scanf("%d%d%d%d",&b,&x,&l,&r); ans=0; for(int i=17;i>=0;i--) { int now=ans+((((b>>i)&1)^1)<<i); if(find(l-1,r,now-x,now+(1<<i)-1-x)) { ans=now; } else { ans+=(((b>>i)&1)<<i); } } printf("%d\n",ans^b); } }
原文:https://www.cnblogs.com/Khada-Jhin/p/9449376.html