【Codeforces Round #693 (Div. 3) E】Correct Placement
阿新 • • 發佈:2021-01-08
題目連結
翻譯
translation
題解
線段樹,只要維護一個以 \(w\) 為下標,然後線段樹上的值維護的是這個範圍的 \(w\) 裡面, 最小的 \(h\) 所在的位置即可。
涉及到一些離散化的操作,所以程式碼看起來比較醜陋。
然後查詢的時候,如果想找小於 \(w\) 和 \(h\) 的,就先在 \(1..w-1\) 這個範圍裡找最小的 \(h_{min}\) 然後用這個 \(h_{min}\) 再和 \(h\) 比較一下。
另外一種橫著的情況類似。(一開始我維護了兩個線段樹,另外一個是以 \(h\) 為下標的。。但是寫完才發現好像一個線段樹就夠用了。。。所以一些沒用的變數請忽視)
程式碼
#include <bits/stdc++.h> #define lson l,mid,rt*2 #define rson mid+1,r,rt*2+1 #define LL long long using namespace std; const int N = 2e5; int n; int h[N+10],w[N+10]; int bhh[2*N+10],bhw[2*N+10]; int hw[2*N+10],wh[2*N+10]; int fanw[2*N+10],fanh[2*N+10]; int a[2*N+10],cnt; int minw[N*2*4],minh[N*2*4]; int fminw(int x,int y){ if (x == -1){ return y; } if (y == -1){ return x; } if (bhw[x] < bhw[y]){ return x; }else{ return y; } } void buildMinW(int l,int r,int rt){ if (l == r){ minw[rt] = hw[l]; return; } int mid = (l+r)/2; buildMinW(lson);buildMinW(rson); minw[rt] = fminw(minw[rt*2],minw[rt*2+1]); } int searchMinW(int L,int R,int l,int r,int rt){ if (L>R){ return -1; } if (L <= l && r <= R){ return minw[rt]; } int mid = (l+r)/2; int pleft = -1,pright = -1; if (L<=mid){ pleft = searchMinW(L,R,lson); } if (mid<R){ pright = searchMinW(L,R,rson); } if (pleft==-1 && pright==-1){ return -1; } if (pleft == -1) { return pright; } if (pright==-1){ return pleft; } return fminw(pleft,pright); } int main(){ ios::sync_with_stdio(0),cin.tie(0); int T,nn = 0; cin >> T; while (T--){ cin >> n; cnt = 0; for (int i = 1;i <= n; i++){ cin >> h[i] >> w[i]; a[++cnt] = h[i]; a[++cnt] = w[i]; } sort(a+1,a+1+cnt); nn = unique(a+1,a+1+cnt)-(a+1); for (int i = 1;i <= nn; i++){ hw[i] = -1; } for (int i = 1;i <= nn*4; i++){ minw[i] = -1; } for (int i = 1;i <= n; i++){ bhh[i] = lower_bound(a+1,a+1+nn,h[i]) - a; bhw[i] = lower_bound(a+1,a+1+nn,w[i]) - a; if (hw[bhh[i]]==-1 || bhw[i] < bhw[hw[bhh[i]]]){ hw[bhh[i]] = i; } } //a[1..n] unique! //cout << lower_bound(a+1,a+1+n,2) - a << endl; index from 1 buildMinW(1,nn,1); for (int i = 1;i <= n; i++){ int th = bhh[i],tw = bhw[i]; //1..th-1,1..tw-1 int p = searchMinW(1,th-1,1,nn,1); if (p!=-1 && bhw[p]<tw){ cout << p <<" "; continue; } p = searchMinW(1,tw-1,1,nn,1); if (p!=-1 && bhw[p]<th){ cout << p <<" "; continue; } cout <<"-1 "; } cout << endl; } return 0; }