[bzoj3524]Couriers
考虑可持久化权值线段树,维护区间和
那么发现满足条件的最多只有一个点,因此从若左区间有超过k个走左区间,右区间有走右区间,都没有就没答案
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 500005 4 #define mid (l+r>>1) 5 map<int,int>mat; 6 int V,n,m,x,y,r[N],a[N],f[N*20],ls[N*20],rs[N*20]; 7 void update(int k1,int &k2,int l,int r,int x){ 8 k2=++V; 9 if (l==r){ 10 f[k2]=f[k1]+1; 11 return; 12 } 13 ls[k2]=ls[k1]; 14 rs[k2]=rs[k1]; 15 if (x<=mid)update(ls[k1],ls[k2],l,mid,x); 16 else update(rs[k1],rs[k2],mid+1,r,x); 17 f[k2]=f[ls[k2]]+f[rs[k2]]; 18 } 19 int query(int k1,int k2,int l,int r,int x){ 20 if (l==r)return l; 21 if (f[ls[k2]]-f[ls[k1]]>x)return query(ls[k1],ls[k2],l,mid,x); 22 if (f[rs[k2]]-f[rs[k1]]>x)return query(rs[k1],rs[k2],mid+1,r,x); 23 return 0; 24 } 25 int main(){ 26 scanf("%d%d",&n,&m); 27 for(int i=1;i<=n;i++){ 28 scanf("%d",&x); 29 if (!mat[x]){ 30 mat[x]=++y; 31 a[y]=x; 32 } 33 update(r[i-1],r[i],1,n,mat[x]); 34 } 35 for(int i=1;i<=m;i++){ 36 scanf("%d%d",&x,&y); 37 printf("%d\n",a[query(r[x-1],r[y],1,n,(y-x+1)/2)]); 38 } 39 }