题意:给定一个长为n的序列,有m次强制在线的询问,每次询问位置【L,R】中abs(a[i]-p)第k小的值
n,m<=1e5,a[i]<=1e6,p<=1e6,k<=169
思路:主席树外面套个二分
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 typedef unsigned int uint; 5 typedef unsigned long long ull; 6 typedef pair<int,int> PII; 7 typedef pair<ll,ll> Pll; 8 typedef vector<int> VI; 9 #define N 1100000 10 #define M 4100000 11 #define fi first 12 #define se second 13 #define MP make_pair 14 #define pi acos(-1) 15 #define mem(a,b) memset(a,b,sizeof(a)) 16 #define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++) 17 #define per(i,a,b) for(int i=(int)a;i>=(int)b;i--) 18 #define lowbit(x) x&(-x) 19 #define Rand (rand()*(1<<16)+rand()) 20 #define id(x) ((x)<=B?(x):m-n/(x)+1) 21 #define ls p<<1 22 #define rs p<<1|1 23 24 const ll MOD=998244353,inv2=(MOD+1)/2; 25 double eps=1e-6; 26 int INF=1e9; 27 28 struct node 29 { 30 int l,r,s; 31 }t[N*20]; 32 33 int root[N],cnt; 34 35 int read() 36 { 37 int v=0,f=1; 38 char c=getchar(); 39 while(c<48||57<c) {if(c==‘-‘) f=-1; c=getchar();} 40 while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar(); 41 return v*f; 42 } 43 44 void update(int l,int r,int x,int &p) 45 { 46 t[++cnt]=t[p]; 47 p=cnt; 48 t[p].s++; 49 if(l==r) return; 50 int mid=(l+r)>>1; 51 if(x<=mid) update(l,mid,x,t[p].l); 52 else update(mid+1,r,x,t[p].r); 53 } 54 55 int query(int l,int r,int x,int y,int p1,int p2) 56 { 57 if(x<=l&&r<=y) return t[p2].s-t[p1].s; 58 int mid=(l+r)>>1; 59 int tmp=0; 60 if(x<=mid) tmp+=query(l,mid,x,y,t[p1].l,t[p2].l); 61 if(y>mid) tmp+=query(mid+1,r,x,y,t[p1].r,t[p2].r); 62 return tmp; 63 } 64 65 int main() 66 { 67 //freopen("1.in","r",stdin); 68 //freopen("1.out","w",stdout); 69 int cas=read(); 70 while(cas--) 71 { 72 int n=read(),q=read(); 73 rep(i,1,cnt) t[i].l=t[i].r=t[i].s=0; 74 cnt=1; root[0]=1; 75 rep(i,1,n) 76 { 77 int x=read(); 78 root[i]=root[i-1]; 79 update(1,1e6,x,root[i]); 80 } 81 int ans=0; 82 rep(i,1,q) 83 { 84 int l=read(),r=read(),p=read(),k=read(); 85 l^=ans; r^=ans; p^=ans; k^=ans; 86 int left=0,right=1e6; 87 ans=1e6; 88 while(left<=right) 89 { 90 int mid=(left+right)>>1; 91 int x=max(1,p-mid),y=min(1000000,p+mid); 92 int t=query(1,1e6,x,y,root[l-1],root[r]); 93 if(t>=k){ans=mid; right=mid-1;} 94 else left=mid+1; 95 } 96 printf("%d\n",ans); 97 } 98 } 99 return 0; 100 }
【HDOJ6621】K-th Closest Distance(主席树,二分)
原文:https://www.cnblogs.com/myx12345/p/11644111.html