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;
}
【Codeforces Round #693 (Div. 3) E】Correct Placement
原文:https://www.cnblogs.com/AWCXV/p/14239874.html