POJ 2761 离线线段树

来源:互联网 发布:淘宝正品篮球鞋店铺 编辑:程序博客网 时间:2024/04/29 07:32

题意:给出每只狗的pretty value,然后多次询问,每次输出区间[i,j](狗站成一排,从第i只到第j只)的第k小的值是多少。区间之间有交叉,但是没有完全包含。

#include "iostream"#include "algorithm"#include "stdlib.h"#include "stdio.h"using namespace std;const int maxn=100010;struct Value{int id,x;}value[maxn];struct Feed{int l,r,x,id;}feed[maxn];struct comp{int l,r,sum;}data[4*maxn];int a[100010];int ans[50010];int mapping[100010];int cmp1(const void *a,const void *b){    return ((Value *)a)->x-((Value *)b)->x;}int cmp2(const void *a,const void *b){    return ((Feed *)a)->l-((Feed *)b)->l;}void build(int l,int r,int k){int mid;data[k].l=l;data[k].r=r;data[k].sum=0;if (l==r)  return ;mid=(l+r)/2;build(l,mid,k*2);build(mid+1,r,k*2+1);}void insert(int n,int k,int op){int mid;data[k].sum+=op;if (data[k].l==n && data[k].r==n)return ;mid=(data[k].l+data[k].r)/2;if (n<=mid) insert(n,k*2,op);else insert(n,k*2+1,op);}int search(int k,int op){if (data[k].l==data[k].r) return data[k].l;if (data[k*2].sum>=op) return search(k*2,op);else return search(k*2+1,op-data[k*2].sum);}int main(){int n,m,i,j,ll,rr;while (scanf("%d%d",&n,&m)!=EOF){for (i=0;i<n;i++){scanf("%d",&a[i]);value[i].id=i; value[i].x=a[i];}qsort(value,n,sizeof(Value),cmp1);for (i=0;i<n;i++)a[value[i].id]=i;for (i=0;i<m;i++){scanf("%d%d%d",&feed[i].l,&feed[i].r,&feed[i].x);feed[i].l--;feed[i].r--;feed[i].id=i;}qsort(feed,m,sizeof(Feed),cmp2);build(0,n-1,1);ll=rr=0;for (i=0;i<m;i++){if (rr==0){ll=feed[i].l;rr=feed[i].r;}elseif (feed[i].l>rr){for (j=ll;j<=rr;j++)insert(a[j],1,-1);ll=feed[i].l;rr=feed[i].r;}else{for (j=ll;j<feed[i].l;j++)insert(a[j],1,-1);ll=rr+1;rr=feed[i].r;}for (j=ll;j<=rr;j++)insert(a[j],1,1);ll=feed[i].l;rr=feed[i].r;ans[feed[i].id]=value[search(1,feed[i].x)].x;}for (i=0;i<m;i++)printf("%d\n",ans[i]);}return 0;}


0 0
原创粉丝点击