码迷,mamicode.com
首页 > 其他好文 > 详细

[SCOI2016]美味(可持久化线段树)

时间:2018-12-14 21:05:40      阅读:125      评论:0      收藏:0      [点我收藏+]

标签:trie树   iostream   函数   math   span   getch   ios   tchar   没有   

可持久化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\n",check(b,x,root[l-1],root[r])^b);
    }
    return 0;
}

[SCOI2016]美味(可持久化线段树)

标签:trie树   iostream   函数   math   span   getch   ios   tchar   没有   

原文地址:https://www.cnblogs.com/Xu-daxia/p/10121495.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!