• [SCOI2016]美味


    [SCOI2016]美味

    题目大意:

    给定一个长度为(n(nle2 imes10^5))的数列(a_i(0le a_ile10^5))(m(mle10^5))次询问,每次询问给定(b_i,x_i,l_i,r_i),对于(jin[l_i,r_i]),求(b_ioplus(a_j+x_i))的最大值。

    思路:

    对于单纯异或的情况,显然可以直接使用可持久化字典树。对于带加法的情况,我们同样可以按位考虑。对每次加入的权值建立主席树,保证主席树建立的区间为([0,2^k))。每次区间左右子结点将这些数按最高位分开,在树上按位贪心,尽量选取与当前位不同的即可。由于含有加法,我们把主席树的区间平移(x_i)即可。时间复杂度(mathcal O(nlog^2n))

    源代码:

    #include<cstdio>
    #include<cctype>
    #include<algorithm>
    inline int getint() {
    	register char ch;
    	while(!isdigit(ch=getchar()));
    	register int x=ch^'0';
    	while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
    	return x;
    }
    const int N=2e5+1,M=262144,logM=18;
    const int SIZE=M*logM;
    class FotileTree {
    	private:
    		struct Node {
    			int val,left,right;
    		};
    		Node node[SIZE];
    		int sz,new_node(const int &p) {
    			node[++sz]=node[p];
    			return sz;
    		}
    	public:
    		int root[N];
    		void insert(int &p,const int &b,const int &e,const int &x) {
    			p=new_node(p);
    			node[p].val++;
    			if(b==e) return;
    			const int mid=(b+e)>>1;
    			if(x<=mid) insert(node[p].left,b,mid,x);
    			if(x>mid) insert(node[p].right,mid+1,e,x);
    		}
    		int count(const int &p,const int &q,const int &b,const int &e,const int &l,const int &r) const {
    			if(node[p].val-node[q].val==0) return 0;
    			if(b==l&&e==r) return node[p].val-node[q].val;
    			const int mid=(b+e)>>1;
    			int ret=0;
    			if(l<=mid) ret+=count(node[p].left,node[q].left,b,mid,l,std::min(mid,r));
    			if(r>mid) ret+=count(node[p].right,node[q].right,mid+1,e,std::max(mid+1,l),r);
    			return ret;
    		}
    		int query(const int &p,const int &q,const int &b,const int &e,const int &x,const int &a,const int &k) const {
    			if(b==e) return b;
    			const int mid=(b+e)>>1;
    			if(a&(1<<k)) {
    				if(mid>=x&&count(root[p],root[q],0,M-1,std::max(b-x,0),mid-x)) {
    					return query(p,q,b,mid,x,a,k-1);
    				} else {
    					return query(p,q,mid+1,e,x,a,k-1);
    				}
    			} else {
    				if(e>=x&&count(root[p],root[q],0,M-1,std::max(mid+1-x,0),e-x)) {
    					return query(p,q,mid+1,e,x,a,k-1);
    				} else {
    					return query(p,q,b,mid,x,a,k-1);
    				}
    			}
    		}
    };
    FotileTree t;
    int main() {
    	const int n=getint(),m=getint();
    	for(register int i=1;i<=n;i++) {
    		t.insert(t.root[i]=t.root[i-1],0,M-1,getint());
    	}
    	for(register int i=0;i<m;i++) {
    		const int b=getint(),x=getint(),l=getint(),r=getint();
    		printf("%d
    ",b^t.query(r,l-1,0,M-1,x,b,17));
    	}
    	return 0;
    }
    
  • 相关阅读:
    ubuntu18.04更新源
    机器学习网址
    ubuntu18.04下安装Anaconda及numpy、matplotlib
    google云使用记录
    tensorflow省钱方案-ml-engine
    Angular 创建项目
    Angular 环境搭建
    android APP国际化一键切换实现
    android 上下滑动标题栏和状态栏改变颜色实现
    android滑动标题栏渐变实现
  • 原文地址:https://www.cnblogs.com/skylee03/p/9179633.html
Copyright © 2020-2023  润新知