【BZOJ】3524 [POI2014] Couriers(主席树)

题目

传送门:QWQ

传送到洛谷QWQ

 

 

分析

 

把求区间第k大的改一改就ok了。

 

 

代码

 

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int N=500010;
 4 int root[N*40], ls[N*40], rs[N*40], sum[N*40];
 5 int n, m, newp;
 6 
 7 void add(int l,int r,int x,int& cur,int cur1)
 8 {
 9     cur=++newp;
10     ls[cur]=ls[cur1]; rs[cur]=rs[cur1];  sum[cur]=sum[cur1]+1;
11     if(l==r) return; int mid=l+r>>1;
12     if(x<=mid) add(l,mid,x,ls[cur],ls[cur1]);
13     else add(mid+1,r,x,rs[cur],rs[cur1]);
14 }
15 
16 int query(int l,int r,int k,int cur,int cur1)
17 {
18     if(l==r) return l;
19     int mid=l+r>>1, cmp1=sum[ls[cur1]]-sum[ls[cur]], cmp2=sum[rs[cur1]]-sum[rs[cur]];
20     if(cmp1>k)  return query(l,mid,k,ls[cur],ls[cur1]);
21     else if(cmp2>k) return query(mid+1,r,k,rs[cur],rs[cur1]);
22     return 0;
23 }
24 
25 int main()
26 {
27     scanf("%d%d",&n,&m);
28     for(int i=1;i<=n;i++)
29     {
30         int x; scanf("%d",&x);
31         add(1,n,x,root[i],root[i-1]);
32     }
33     
34     for(int i=1;i<=m;i++)
35     {
36         int l,r; scanf("%d%d",&l,&r);
37         printf("%d\n",query(1,n,r-l+1>>1,root[l-1],root[r]));
38     }
39     return 0;
40 }

 

 


 

posted @ 2018-02-07 17:03  noble_(noblex)  阅读(148)  评论(0编辑  收藏  举报
/* */