[SCOI2016]美味 贪心+主席树
Posted 20020723yjx
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[SCOI2016]美味 贪心+主席树相关的知识,希望对你有一定的参考价值。
挺水的一道题。
题目大意:每个询问给出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 "); //#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]美味 贪心+主席树的主要内容,如果未能解决你的问题,请参考以下文章