2018牛客多校6 - I Team Rocket KD樹維護空間
阿新 • • 發佈:2018-08-05
再次 double sync main get set print esp operator
題意:給出n條鐵路區間\([L,R]\),共有m個boom依時間順序放置在\(k_i\)中,區間與\(k_i\)有交集的都被炸掉
求每次炸掉的鐵路個數和最後輸出所有id被炸的時間點
炸彈能炸到的區間滿足\(L≤K≤R\)
因為\(L\)與\(R\)無關,將其關系改寫為\(X≤K≤Y\),
對應於二維空間,鐵路區間相當於一個點\((L,R)\),每次詢問有多少個沒被屏蔽的點滿足\(X≤K\)且\(K≤Y\)
然後KD樹亂搞剪枝就好
唯一的問題是屏蔽掉的點無法在push_up時再次更新兩個維度的極左極右值\(lx,rx\)(要麽再多維護次左次右值)
幸好沒被卡(反而跑的賊快
#include<bits/stdc++.h> #define rep(i,j,k) for(register int i=j;i<=k;i++) #define rrep(i,j,k) for(register int i=j;i>=k;i--) #define erep(i,u) for(register int i=head[u];~i;i=nxt[i]) #define print(a) printf("%lld",(ll)a) #define println(a) printf("%lld\n",(ll)a) #define printbk(a) printf("%lld ",(ll)a) #define IOS ios::sync_with_stdio(0) using namespace std; const int MAXN = 3e5+11; const int INF = 0x3f3f3f3f; const double EPS = 1e-7; typedef long long ll; const ll MOD = 998244353; ll read(){ ll x=0,f=1;register char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} return x*f; } int D,CLOCK; int ans[MAXN]; ll sum,prod; struct POINT{ int x[2],idx; bool operator < (const POINT &rhs) const{ return x[D]<rhs.x[D]; } }p[MAXN]; struct KD{ int lx[MAXN][2],rx[MAXN][2]; int son[MAXN][2],size[MAXN]; int mark[MAXN]; int root; #define lc son[o][0] #define rc son[o][1] void pu(int o){ size[o]=mark[o]; if(lc) size[o]+=size[lc]; if(rc) size[o]+=size[rc]; rep(i,0,1){ if(lc&&lx[lc][i]<lx[o][i]) lx[o][i]=lx[lc][i]; if(rc&&lx[rc][i]<lx[o][i]) lx[o][i]=lx[rc][i]; if(lc&&rx[lc][i]>rx[o][i]) rx[o][i]=rx[lc][i]; if(rc&&rx[rc][i]>rx[o][i]) rx[o][i]=rx[rc][i]; } } int build(int d,int l,int r){ int mid=l+r>>1; D=d; mark[mid]=1; nth_element(p+l,p+mid,p+r+1); rep(i,0,1) lx[mid][i]=rx[mid][i]=p[mid].x[i]; size[mid]=1;son[mid][0]=son[mid][1]=0; if(l<mid) son[mid][0]=build(d^1,l,mid-1); if(r>mid) son[mid][1]=build(d^1,mid+1,r); pu(mid); return mid; } void query(int o,int k){ if(!o) return; if(!size[o]) return; if(lx[o][0]>k||rx[o][1]<k) return; if(mark[o]&&p[o].x[0]<=k&&p[o].x[1]>=k){ ans[p[o].idx]=CLOCK; sum++; prod=(prod*p[o].idx)%MOD; mark[o]=0; } if(lc) query(lc,k); if(rc) query(rc,k); pu(o); } }kd; int main(){ int T=read(),kase=0,n,m; while(T--){ n=read(); m=read(); rep(i,1,n){ p[i].x[0]=read(); p[i].x[1]=read(); p[i].idx=i; } memset(ans,0,sizeof ans); //kd.baoli(); kd.root=kd.build(0,1,n); ll lastans=0; CLOCK=0; printf("Case #%d:\n",++kase); while(m--){ sum=0; prod=1; ll pos=lastans^read(); ++CLOCK; kd.query(kd.root,pos); println(sum); if(sum) lastans=prod; else lastans=0; } rep(i,1,n){ if(i==n) println(ans[i]); else printbk(ans[i]); } } return 0; }
2018牛客多校6 - I Team Rocket KD樹維護空間