zoukankan      html  css  js  c++  java
  • P3293 [SCOI2016]美味 主席树+按位贪心

    给定长度为 (n) 序列 (a[i]) ,每次询问区间 ([l,r]) ,并给定 (b,x) 中的一个数 (p=a[i]) ,使得最大化 (b igoplus p^x)

    主席树+按位贪心。
    我们可以直接贪每一位长什么样子,然后再主席树上区间查询即可。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #define R register int
    using namespace std;
    namespace Luitaryi {
    inline int g() { R x=0,f=1;
    	register char s; while(!isdigit(s=getchar())) f=s=='-'?-1:f;
    	do x=x*10+(s^48); while(isdigit(s=getchar())); return x*f;
    } const int N=200010,B=17;
    int n,m,L,tot,a[N];
    int sum[N*20],ls[N*20],rs[N*20],rt[N];
    inline void ins(int& tr,int t,int l,int r,int p) {
    	tr=++tot; sum[tr]=sum[t]+1,ls[tr]=ls[t],rs[tr]=rs[t];
    	if(l==r) return ; R md=l+r>>1;
    	p<=md?ins(ls[tr],ls[t],l,md,p):ins(rs[tr],rs[t],md+1,r,p);
    }
    inline bool query(int tr,int t,int l,int r,int LL,int RR) {
    	if(r<LL||l>RR||sum[tr]-sum[t]<=0) return 0;
    	if(l==r) return sum[tr]-sum[t];
    	R md=l+r>>1;
    	return (LL<=md&&ls[tr]&&query(ls[tr],ls[t],l,md,LL,RR))
    				||(RR>md&&rs[tr]&&query(rs[tr],rs[t],md+1,r,LL,RR));
    }
    inline void main() {
    	n=g(),m=g();
    	for(R i=1;i<=n;++i) a[i]=g(),L=max(L,a[i]);
    	for(R i=1;i<=n;++i) ins(rt[i],rt[i-1],0,L,a[i]);
    	for(R i=1,b,x,l,r,ans;i<=m;++i) { ans=0;
    		b=g(),x=g(),l=g(),r=g();
    		for(R t=B;~t;--t) {
    			if((b>>t&1)&&!query(rt[r],rt[l-1],0,L,ans-x,ans+(1<<t)-1-x)) ans+=1<<t;
    			if(!(b>>t&1)&&query(rt[r],rt[l-1],0,L,ans+(1<<t)-x,ans+(1<<t+1)-1-x)) ans+=1<<t;
    		} printf("%d
    ",b^ans);
    	}
    }
    } signed main() {Luitaryi::main(); return 0;}
    

    2019.11.23

  • 相关阅读:
    今日总结
    今日总结
    今日总结
    今日总结
    今日总结
    java自学
    java自学
    Java自学
    Java自学
    java自学
  • 原文地址:https://www.cnblogs.com/Jackpei/p/11919861.html
Copyright © 2011-2022 走看看