codevs 2021 中庸之道

所谓[l,r]的中位数?就是区间第(r-l+2)大。

主席树乱搞之。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
#define maxn 1005
using namespace std;
int num[maxn],hash[maxn],n,q,tot=0,a,b,c;
int ls[maxn*20],rs[maxn*20],sum[maxn*20],root[maxn];
void build(int left,int right,int fath,int ftype)
{
int rt=++tot;
if (ftype==1) ls[fath]=rt;
else rs[fath]=rt;
sum[rt]=0;
if (left==right) return;
int mid=(left+right)>>1;
build(left,mid,rt,1);
build(mid+1,right,rt,2);
}
void update(int left,int right,int p,int last,int rt,int fath,int ftype)
{
rt=++tot;
if (ftype==1) ls[fath]=rt;
else rs[fath]=rt;
ls[rt]=ls[last];
rs[rt]=rs[last];
sum[rt]=sum[last]+1;
if (left==right) return;
int mid=(left+right)>>1;
if (p<=mid) update(left,mid,p,ls[last],ls[rt],rt,1);
else update(mid+1,right,p,rs[last],rs[rt],rt,2);
}
int query(int left,int right,int c,int last,int rt)
{
if (left==right) return left;
int cnt=sum[ls[rt]]-sum[ls[last]];
int mid=(left+right)>>1;
if (c<=cnt) return query(left,mid,c,ls[last],ls[rt]);
else return query(mid+1,right,c-cnt,rs[last],rs[rt]);
}
int main()
{
scanf("%d%d",&n,&q);
for (int i=1;i<=n;i++)
{
scanf("%d",&num[i]);
hash[i]=num[i];
}
sort(hash+1,hash+n+1);
int cnt=unique(hash+1,hash+n+1)-hash-1;
root[0]=1;
build(1,cnt,0,0);
for (int i=1;i<=n;i++)
num[i]=lower_bound(hash+1,hash+n+1,num[i])-hash;
for (int i=1;i<=n;i++)
{
root[i]=tot+1;
update(1,cnt,num[i],root[i-1],root[i],0,0);
}
for (int i=1;i<=q;i++)
{
scanf("%d%d",&a,&b);
c=(b-a+2)/2;
int ans=query(1,cnt,c,root[a-1],root[b]);
printf("%d\n",hash[ans]);
}
return 0;
}

你可能感兴趣的:(codevs 2021 中庸之道)