[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; }