1. 程式人生 > >[SCOI2016]美味 貪心+主席樹

[SCOI2016]美味 貪心+主席樹

div 是否 == mes min query www gcc spa

挺水的一道題。

題面傳送門

題目大意:每個詢問給出b,x,l,r,求[l~r]區間內b xor (x+a[i]) (l<=i<=r) 的最大值。

秒想到trie樹上貪心?

好像還有加法啊,直接套可持久化trie樹行不通,怎麽玩呢。

假設目前處理到第j位,b轉成二進制後第j位為1來考慮。設我們目前找到的數是ans,那麽,如果有一個i在[l~r]內,且ans-x<=a[i]<=ans+(1<<j)-1-x,那麽(a[i]+x)^b在第j位必定是1。如果第j位為0,同理,在下就不再贅述。

怎麽處理某個區間內,在某個值域內的數是否存在?

於是就自然而然的想到了主席樹。

咦,好像就可以A了誒。

#include<bits/stdc++.h>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<deque>
#include<list>
#include<set>
#include<vector>
#include<iostream>
#define
ll long long #define re register #define inf 0x3f3f3f3f #define inl inline #define sqr(x) (x*x) //#define eps 1e-8 #define debug printf("debug\n"); //#pragma comment(linker, "/STACK:1024000000,1024000000") //#pragma GCC optimize (2) //#pragma G++ optimize (2) using namespace std; //const ll mod; const ll MAXN=2e5+10
; inl ll read() { re ll x = 0; re int f = 1; char ch = getchar(); while(ch<0||ch>9) { if(ch== - ) f = -1; ch = getchar(); } while(ch>=0&&ch<=9) {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();} return x * f; } inl char readc() { char ch=getchar(); while((z<ch||ch<a)&&(Z<ch||ch<A)) ch=getchar(); return ch; } inl void write(re ll x){ if(x>=10)write(x/10); putchar(x%10+0); } inl void writeln(re ll x){ if(x<0) {x=-x;putchar(-);} write(x); puts(""); } inl ll gcd(re ll x,re ll y){while(y^=x^=y^=x%=y);return x;} inl void FR() { freopen(".in","r",stdin); freopen(".out","w",stdout); } inl void FC() { fclose(stdin); fclose(stdout); } ll a[MAXN],tot,root[MAXN],ans,maxn; struct Node { ll son[2],cnt; }Tree[MAXN<<5]; ll insert(ll pre,ll x,ll l,ll r) { re ll t=++tot;Tree[t]=Tree[pre];Tree[t].cnt++; if(l==r) return t; re ll mid=(l+r)>>1; if(x<=mid) Tree[t].son[0]=insert(Tree[pre].son[0],x,l,mid); else Tree[t].son[1]=insert(Tree[pre].son[1],x,mid+1,r); return t; } ll query(ll x,ll y,ll L,ll R,ll l,ll r) { if(L<=l&&r<=R) return Tree[y].cnt-Tree[x].cnt; re ll mid=(l+r)>>1,sum=0; if(L<=mid) sum+=query(Tree[x].son[0],Tree[y].son[0],L,R,l,mid); if(R>mid) sum+=query(Tree[x].son[1],Tree[y].son[1],L,R,mid+1,r); return sum; } bool Query(ll l,ll r,ll L,ll R) { L=max(0ll,L);R=min(R,maxn); if(L>R) return false; return query(root[l],root[r],L,R,0,maxn); } int main() { // FR(); re ll n=read(),m=read(); for(re ll i=1;i<=n;i++) {a[i]=read();maxn=max(maxn,a[i]);} for(re ll i=1;i<=n;i++) {root[i]=insert(root[i-1],a[i],0,maxn);} for(re ll i=1;i<=m;i++) { re ll b=read(),x=read(),l=read(),r=read();ans=0; for(re ll j=20;~j;j--) { re ll t=ans+((1^((b>>j)&1))<<j); if(Query(l-1,r,t-x,t+(1<<j)-x-1)) ans=t; else ans+=((b>>j)&1)<<j; } writeln(ans^b); } // FC(); return 0; }

[SCOI2016]美味 貪心+主席樹