在线区间查询,可以想到主席树
至于求第k小距离,可以二分
1 #include <bits/stdc++.h>
2 #define For(i,a,b) for(int i=a;i<=b;++i)
3 #define Dec(i,b,a) for(int i=b;i>=a;--i)
4 #define file() freopen("c://users/asus/desktop/v.txt","r",stdin);
5 #define IO ios::sync_with_stdio(0),cin.tie(0)
6 #define inf 0x3f3f3f3f
7 using namespace std;
8 typedef long long ll;
9
10 #define mid (l+r>>1)
11 const int N = 1000000;
12 int s[N*40],lc[N*40],rc[N*40],rt[100010],a[100010];
13 int n,m,kase,ct;
14 void clr(int &x,int l,int r)
15 {
16 s[x=++ct]=0;
17 if(l==r) return;
18 clr(lc[x],l,mid); clr(rc[x],mid+1,r);
19 }
20 void upd(int x,int &y,int l,int r,int p)
21 {
22 s[y=++ct]=s[x]+1;
23 if(l==r) return;
24 if(p<=mid) rc[y]=rc[x], upd(lc[x],lc[y],l,mid,p);
25 if(p>mid) lc[y]=lc[x], upd(rc[x],rc[y],mid+1,r,p);
26 }
27 int qry(int x,int y,int l,int r,int L,int R,int res=0)
28 {
29 if(L<=l&&r<=R) return s[y]-s[x];
30 if(L<=mid) res+=qry(lc[x],lc[y],l,mid,L,R);
31 if(mid<R) res+=qry(rc[x],rc[y],mid+1,r,L,R);
32 return res;
33 }
34 int main()
35 {
36 IO;
37 // file();
38 cin>>kase;
39 while(kase--)
40 {
41 cin>>n>>m;
42 ct=0;
43 clr(rt[0],1,n);
44 For(i,1,n) cin>>a[i],upd(rt[i-1],rt[i],1,N,a[i]);
45 int x=0,y=0,p,k,ans=0;
46 For(i,1,m)
47 {
48 cin>>x>>y>>p>>k;
49 x=x^ans; y=y^ans; p=p^ans; k=k^ans;
50 if(x>y) swap(x,y);
51 int l=0,r=N,mi;
52 while(l<=r)
53 {
54 mi=l+r>>1;
55 if(qry(rt[x-1],rt[y],1,N,p-mi,p+mi)<k) l=mi+1;
56 else ans=mi,r=mi-1;
57 }
58 cout<<ans<<"\n";
59 }
60 }
61 }
觉得自己好菜,不知道今年能不能打区域赛……_(¦3」∠)_
来源:https://www.cnblogs.com/uuuxxllj/p/11300741.html