【主席树】HDU 6621 K-th Closest Distance

在线区间查询,可以想到主席树

至于求第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」∠)_

猜你喜欢

转载自www.cnblogs.com/uuuxxllj/p/11300741.html