【Codeforces Round #693 (Div. 3) E】Correct Placement

题目链接

链接

翻译

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;
}

posted @ 2021-01-06 11:03  AWCXV  阅读(158)  评论(0编辑  收藏  举报