[POI2014]KUR-Couriers

链接

将查询操作改为在l-r内是否有子树的sum超过一半

#include<bits/stdc++.h>
#define re return
#define inc(i,l,r) for(int i=l;i<=r;++i)

using namespace std;
template<typename T>inline void rd(T&x)
{
    char c;bool f=0;
    while((c=getchar())<'0'||c>'9')if(c=='-')f=1;
    x=c^48;
    while((c=getchar())>='0'&&c<='9')x=x*10+(c^48);
    if(f)x=-x;
}

const int maxn=500005;
int n,m,cnt;
int T[maxn],a[maxn],b[maxn];
int L[maxn<<5],R[maxn<<5],sum[maxn<<5];


inline int build(int l,int r)
{
    int rt=++cnt;
    if(l==r)re rt;
    int mid=(l+r)>>1;
    L[rt]=build(l,mid);
    R[rt]=build(mid+1,r);
    re rt;
}

inline int modify(int pre,int l,int r,int x)
{
    int rt=++cnt;
    L[rt]=L[pre];R[rt]=R[pre];sum[rt]=sum[pre]+1;
    if(l==r) re rt;
    int mid=(l+r)>>1;
    if(x<=mid)L[rt]=modify(L[pre],l,mid,x);
    else R[rt]=modify(R[pre],mid+1,r,x);
    re rt;
}

inline int query(int pre,int now,int l,int r,int k)
{
    if(l==r)re l;
    int mid=(l+r)>>1;
    if((sum[L[now]]-sum[L[pre]])*2>k)re query(L[pre],L[now],l,mid,k);
    if((sum[R[now]]-sum[R[pre]])*2>k)re query(R[pre],R[now],mid+1,r,k);
    re 0; 
}

int main()
{
    int x,y; 
    rd(n),rd(m);
    inc(i,1,n)
    {
        rd(a[i]);
        b[i]=a[i];
    }
    
    sort(b+1,b+n+1);
    int N=unique(b+1,b+n+1)-b-1;
    T[0]=build(1,N);
    inc(i,1,n)
    T[i]=modify(T[i-1],1,N,lower_bound(b+1,b+N+1,a[i])-b);
    
    inc(i,1,m)
    {
        rd(x),rd(y);
        printf("%d\n",b[query(T[x-1],T[y],1,N,y-x+1)]);
    }
    re 0;
} 

 

posted @ 2019-08-20 20:17  凉如水  阅读(127)  评论(0编辑  收藏  举报