zoukankan      html  css  js  c++  java
  • [SCOI2016]美味(可持久化线段树)

    可持久化trie树?好像和可持久化权值线段树差不多。。
    如果这题没有那个(x[i])这题就是一个裸的可持久化trie树。
    仔细想想,多了这个(x[i])之后有什么影响?
    就是我们查询区间的时候区间的两个端点减去一个(x[i])就行了。
    但是这样我们查询的可能不是树上的一个节点了,我们在树上二分的时候每一次都要调用一次查询的函数。
    复杂度多一个(log)可以接受。

    #include<iostream>
    #include<cstring>
    #include<cmath>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int N=250000;
    int n,m,tot,sum[N*30],ch[N*30][2],root[N];
    void build(int l,int r,int &now){
    	now=++tot;
    	if(l==r)return;
    	int mid=(l+r)>>1;
    	build(l,mid,ch[now][0]);
    	build(mid+1,r,ch[now][1]);
    }
    void ins(int l,int r,int x,int pre,int &now){
    	now=++tot;
    	sum[now]=sum[pre]+1;
    	if(l==r)return;	
    	int mid=(l+r)>>1;
    	ch[now][1]=ch[pre][1];
    	ch[now][0]=ch[pre][0];
    	if(x>mid)ins(mid+1,r,x,ch[pre][1],ch[now][1]);
    	else ins(l,mid,x,ch[pre][0],ch[now][0]);
    }
    int getsum(int l,int r,int L,int R,int pre,int now){
    	if(L>R)return 0;
    	if(l==L&&r==R){
    		return sum[now]-sum[pre];
    	}
    	int mid=(l+r)>>1;
    	if(L>mid)return getsum(mid+1,r,L,R,ch[pre][1],ch[now][1]);
    	else if(R<=mid)return getsum(l,mid,L,R,ch[pre][0],ch[now][0]);
    	else return getsum(l,mid,L,mid,ch[pre][0],ch[now][0])+
    	getsum(mid+1,r,mid+1,R,ch[pre][1],ch[now][1]);
    }
    int check(int x,int y,int pre,int now){
    	int ans=0;
    	for(int i=17;i>=0;i--){
            int t=ans+((1^((x>>i)&1))<<i);
            if (getsum(0,99999,max(0,t-y),min(t+(1<<i)-1-y,99999),pre,now))ans=t;
            else ans+=((x>>i)&1)<<i;
        }
    	return ans;
    }
    int read(){
    	int sum=0,f=1;char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9'){sum=sum*10+ch-'0';ch=getchar();}
    	return sum*f;
    }
    int main(){
    	n=read();m=read();
    	build(0,99999,root[0]); 
    	for(int i=1;i<=n;i++){
    		int a=read();
    		ins(0,99999,a,root[i-1],root[i]);
    	}
    	while(m--){
    		int b=read(),x=read(),l=read(),r=read();
    		printf("%d
    ",check(b,x,root[l-1],root[r])^b);
    	}
    	return 0;
    }
    
  • 相关阅读:
    java 中的Debug eclipse 开发工具使用
    google 浏览器的Debug 调试工具使用
    java 实现word 转 pdf
    你好啊 未来的自己
    java 实现在线阅读 .pdf
    java 的在线下载文件 .pdf
    Java 实现手机发送短信验证码
    Java 实现发送邮件
    Java 实现邮件的发送
    沃尔沃投资两家以色列科技创企 布局人工智能
  • 原文地址:https://www.cnblogs.com/Xu-daxia/p/10121495.html
Copyright © 2011-2022 走看看