hdu5249--权值线段树

权值线段树,是以权值为下标的线段树,不像普通的线段树一样。
但是对于较大的数据,就需要离散化来解决空间上的不足。
权值线段树这样一说,有点儿像主席树的感觉。空间上也优于主席树。但是它对于子区间却无能为力。它对于一些动态的整个区间上的查询还是比较好用。
就像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|1
using 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;
}
发布了51 篇原创文章 · 获赞 6 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_35776579/article/details/55004134