HDU 4251 划分树

来源:互联网 发布:淘宝换货要申请吗 编辑:程序博客网 时间:2024/05/01 06:26
#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>#include<queue>#include<cmath>#include<vector>#include<set>#include<map>#include<string>using namespace std;#define lc l,m,index<<1#define rc m+1,r,index<<1|1#define N 100005#define ll long long#define inf 0x3f3f3f3f#define MOD 1000000007struct node{    int val[N];//每一层位置的数据    int cnt[N];//区间到这个位置划分到左子树的个数}tree[20];int n,m;int sorted[N];//排好序的数组,初始数组在tree[0].val里面void build(int l,int r,int index){    int m=(l+r)>>1;    if(l==r)return;    int lp=l,rp=m+1,same=m-l+1;//lp是左子树开始位置,rp是右子树开始位置,same是可以划分到左子树与中位数相等的数的个数    int i;    for(i=l;i<=r;i++)same-=tree[index].val[i]<sorted[m];//计算same    for(i=l;i<=r;i++)    {        int flag=0;//是否划分到左子树        if(tree[index].val[i]<sorted[m]||(tree[index].val[i]==sorted[m]&&same))//比中位数小或者和中位数相等并且same不为0        {            tree[index+1].val[lp++]=tree[index].val[i];            flag++;            if(tree[index].val[i]==sorted[m])same--;        }        else//划分到右子树        {            tree[index+1].val[rp++]=tree[index].val[i];        }        if(i==l)tree[index].cnt[i]=flag;        else tree[index].cnt[i]=tree[index].cnt[i-1]+flag;    }    build(l,m,index+1);    build(m+1,r,index+1);}int query(int L,int R,int k,int l,int r,int index){    if(l==r)return l;    int m=(l+r)>>1;    int s,ss;//s是l到L-1划分到左子树的个数,ss是L到R划分到左子树的个数    if(L==l)s=0,ss=tree[index].cnt[R];    else s=tree[index].cnt[L-1],ss=tree[index].cnt[R]-tree[index].cnt[L-1];;    if(ss>=k)return query(l+s,l+s+ss-1,k,l,m,index+1);    else return query(m+L-l+1-s,m+1+R-l-s-ss,k-ss,m+1,r,index+1);}int main(){    int tcase=1;    while(~scanf("%d",&n))    {        int i;        for(i=1;i<=n;i++)        {            scanf("%d",&sorted[i]);            tree[0].val[i]=sorted[i];        }        sort(sorted+1,sorted+1+n);        build(1,n,0);        printf("Case %d:\n",tcase++);        scanf("%d",&m);        while(m--)        {            int a,b,k;            scanf("%d%d",&a,&b);            k=(b-a)/2+1;            printf("%d\n",sorted[query(a,b,k,1,n,0)]);        }    }    return 0;}

0 0
原创粉丝点击