hdu 4251 求区间的中间值

来源:互联网 发布:康熙传位给谁知乎 编辑:程序博客网 时间:2024/06/07 07:51

裸的划分树,也可以用其他方法。

#include<stdio.h>#include<algorithm>#define N 100100using namespace std;struct node{    int x,y,mid;}a[N*4];struct Tree{    int val,num,p;}tree[20][N];int st[N];void build(int x,int y,int cen,int t){    int m;    a[t].x=x; a[t].y=y; m=a[t].mid=(x+y)>>1;    Tree *last=tree[cen-1],*cur=tree[cen];    int mid=st[m],i,sum=0,l=x,r=m+1;    for(i=m;i>=x;i--)    {        if(st[i]==mid)            sum++;        else            break;    }    for(i=x;i<=y;i++)    {      int v=last[i].val;      if(v==mid)      {          if(sum)          {              cur[l++].val=mid;              last[i].num=last[i].p=0;              sum--;          }          else          {              cur[r++].val=mid;              last[i].num=last[i].p=1;          }      }      else if(v<mid)      {          cur[l++].val=v;          last[i].num=last[i].p=0;      }      else      {          cur[r++].val=v;          last[i].num=last[i].p=1;      }    }    for(i=x+1;i<=y;i++)        last[i].num+=last[i-1].num;    if(x==y)  return;    build(x,m,cen+1,t*2);    build(m+1,y,cen+1,t*2+1);}int query(int x,int y,int k,int cen,int t){    int mid=a[t].mid;    Tree l=tree[cen][x],r=tree[cen][y];    if(a[t].x==a[t].y)        return l.val;    int dif=(y-x+1)-(r.num-l.num+l.p);    if(dif>=k)        return query(x-l.num+l.p,y-r.num,k,cen+1,t*2);    else        return query(mid+l.num+1-l.p,mid+r.num,k-dif,cen+1,t*2+1);}int main(){    int n,m,i,cnt=1,j,k,b,c;    while(scanf("%d",&n)!=EOF)    {        for(i=1;i<=n;i++)        {            scanf("%d",&st[i]);            tree[0][i].val=st[i];        }        sort(st+1,st+1+n);        build(1,n,1,1);        scanf("%d",&m);        printf("Case %d:\n",cnt++);        for(i=1;i<=m;i++)        {            scanf("%d%d",&c,&b);            k=(b-c)/2+1;            printf("%d\n",query(c,b,k,0,1));        }    }    return 0;}


0 0
原创粉丝点击