zoukankan      html  css  js  c++  java
  • 【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;
    }
    
    
  • 相关阅读:
    优先队列用法详解
    chenzl
    2020面向对象程序设计寒假作业1
    1.自我介绍

    洛谷U32670 小凯的数字(比赛)
    洛谷1417 烹调方案
    高等软工课程总结
    西电B楼导航
    毕业前夕随想
  • 原文地址:https://www.cnblogs.com/AWCXV/p/14239874.html
Copyright © 2011-2022 走看看