hdu5249--权值线段树

来源:互联网 发布:ubuntu 14.04 iso下载 编辑:程序博客网 时间:2024/05/01 18:30

权值线段树,是以权值为下标的线段树,不像普通的线段树一样。
但是对于较大的数据,就需要离散化来解决空间上的不足。
权值线段树这样一说,有点儿像主席树的感觉。空间上也优于主席树。但是它对于子区间却无能为力。它对于一些动态的整个区间上的查询还是比较好用。
就像hdu5249就是动态中位数,就可以这样来处理。

附上代码:

#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#include<queue>#define For(aa,bb,cc) for(int aa=bb;aa<=cc;++aa)#define Set(aa,bb) memset(aa,bb,sizeof(aa))#define ls node<<1#define rs node<<1|1using namespace std;const int maxn=10010;int pre[maxn],now[maxn],tree[maxn<<2];int n,Case;void pushup(int node){    tree[node]=tree[ls]+tree[rs];}void create_tree(int node,int l,int r){    if(l==r){        tree[node]=0;        return ;    }    int mid=(l+r)>>1;    create_tree(ls,l,mid);    create_tree(rs,mid+1,r);    pushup(node);    return ;}void update(int node,int l,int r,int w,int flag){    if(l==r){        tree[node]+=flag;        return ;     }    int mid=(l+r)>>1;    if(w<=mid) update(ls,l,mid,w,flag);    else update(rs,mid+1,r,w,flag);    pushup(node);}int query(int node,int l,int r,int flag){    if(l==r) return l;    int mid=(l+r)>>1;    if(flag<=tree[ls]) return query(ls,l,mid,flag);    else return query(rs,mid+1,r,flag-tree[ls]);}void work(){    queue<int>q;    ++Case;    printf("Case #%d:\n",Case);    For(i,1,n){        char s[10];        scanf("%s",s);        if(s[0]=='i') scanf("%d",&pre[i]);        else if(s[0]=='o') pre[i]=-1;        else pre[i]=-2;    }    int sum=0;    For(i,1,n){        if(pre[i]>=0) now[++sum]=pre[i];    }    sort(now+1,now+1+sum);    sum=unique(now+1,now+sum+1)-(now+1);    create_tree(1,1,sum);    For(i,1,n){        if(pre[i]>=0){            int tmp=lower_bound(now+1,now+1+sum,pre[i])-now;            update(1,1,sum,tmp,1);            q.push(pre[i]);        }        else if(pre[i]==-1){            int ret=q.front();            int tmp=lower_bound(now+1,now+1+sum,ret)-now;            update(1,1,sum,tmp,-1);            q.pop();        }        else{            int md=query(1,1,sum,(q.size()/2)+1);            printf("%d\n",now[md]);        }    }}int main(){#ifndef ONLINE_JUDGE    freopen("in.txt","r",stdin);    freopen("out.txt","w",stdout);#endif    while(~scanf("%d",&n)) work();    return 0;}
0 0
原创粉丝点击