BZOJ4571: [SCOI2016] Delicious - Problem Solving

https://www.lydsy.com/JudgeOnline/problem.php?id=4571

https://www.luogu.org/problemnew/show/P3293

A restaurant has n dishes, numbered 1...n, and everyone's evaluation value for the i-th dish is ai(1<=i<=n). There are m customers, the ith customer's expectation value is bi, and his preference value is xi. Therefore, the i-th customer considers the j-th dish's deliciousness to be bi XOR (aj+xi), where XOR represents the exclusive OR operation.

The i-th customer wants to pick out the dishes that he thinks are the most delicious, that is, the dishes with the most delicious value, but due to factors such as price, he can only choose from the li-th to ri-th courses. Please help them find the tastiest dish.

Take a look, it's great! The Persistent Trie of Luogu Proving Ground is finally a truly Persistent Trie!

Wait, how can you add x, emmm...

So we knocked down our own board and started over again. Instead of building a trie with the previous (I wrote) board, we used a range to build a persistent trie tree.

(But in fact, the construction methods are similar...began to doubt whether the previous practice can be transferred.)

This becomes for each bit of b (of course, greedily from high to low), we look for the qualified value range -x whether there is this bit after the XOR and then it is 1.

(Anyway, when I understand it, I understand it by reading the code. I feel that the principle is very confusing. I believe everyone can read the code to understand 233)

#include<cmath>
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=2e5+5;
const int mx=1e5-1;
inline int read(){
    int X=0,w=0;char ch=0;
    while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
    while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
    return w?-X:X;
}
struct trie{
    int a[2],sz;
}tr[N*20];
int tot,rt[N],pool,n,m;
void insert(int y,int &x,int l,int r,int k){
    tr[x =++pool]= tr[y];
    tr[x].sz++;
    if(l==r)return;
    int mid=(l+r)>>1;
    if(k<=mid)insert(tr[y].a[0],tr[x].a[0],l,mid,k);
    else insert(tr[y].a[1],tr[x].a[1],mid+1,r,k);
    return;
}
int query(int nl,int nr,int l,int r,int L,int R){
    if(l==L&&r==R)return tr[nr].sz-tr[nl].sz;
    int mid=(l+r)>>1;
    if(R<=mid)return query(tr[nl].a[0],tr[nr].a[0],l,mid,L,R);
    else if(L>mid)return query(tr[nl].a[1],tr[nr].a[1],mid+1,r,L,R);
    else return query(tr[nl].a[0],tr[nr].a[0],l,mid,L,mid)+
                query(tr[nl].a[1],tr[nr].a[1],mid+1,r,mid+1,R);
}
int ask(int l,int r,int k,int x){
    int ans=0;
    for(int i=18;i>=0;i--){
        int L,R;
        bool p=k&(1<<i);
        if(p)L=ans,R=ans+(1<<i)-1;
        else L=ans+(1<<i),R=ans+(1<<i+1)-1;
        L=max(L-x,0),R=min(R-x,mx);
        if(L<=R&&query(rt[l-1],rt[r],0,mx,L,R))ans+=(1<<i)*(p^1);
        else ans+=(1<<i)*p;
    }
    return ans^k;
}
int main(){
    n=read(),m=read();
    for(int i=1;i<=n;i++){
        insert(rt[i-1],rt[i],0,mx,read());
    }
    for(int i=1;i<=m;i++){
        int k=read(),x=read(),l=read(),r=read();
        printf("%d\n",ask(l,r,k,x));
    }
    return 0;
}

+++++++++++++++++++++++++++++++++++++++++++

+ Author of this article: luyouqi233. +

+Welcome to my blog: http://www.cnblogs.com/luyouqi233/ +

+++++++++++++++++++++++++++++++++++++++++++

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324993357&siteId=291194637