1. 程式人生 > >ACM-ICPC 2018 徐州賽區網絡預賽 G. Trace (set維護)

ACM-ICPC 2018 徐州賽區網絡預賽 G. Trace (set維護)

sin scan 另一個 pri pre reverse 第一個 acm-icpc 有一個

註意題目保證不會有一個矩形完全包括另一個矩形的情況
時間序上從後往前看,一個坐標$(x,y)$加進來之前,如果已經有$x_i<x$,則對結果的貢獻為$x-x_i$;若不存在$x_i<x$,則對結果的貢獻為$x$.縱坐標$y$同理.
用兩個集合維護已經存在的橫縱坐標,每次用set自帶的lower_bound查找第一個大於等於當前x和y的值,然後將叠代器--以查找上一個元素(即第一個小於它的元素).

#include<bits/stdc++.h>
#define X first
#define Y second
using namespace std;
typedef long long LL;
pair<LL,LL> vz[50005];
set<LL> dp1;           //X
set<LL> dp2;           //Y
int main()
{
    #ifndef ONLINE_JUDGE
        freopen("in.txt","r",stdin);
        freopen("out.txt","w",stdout);
    #endif
    set<LL> :: iterator it;
    set<LL> :: reverse_iterator ir;
    int n;
    while(scanf("%d",&n)==1){
        dp1.clear();
        dp2.clear();
        for(int i=1;i<=n;++i) scanf("%lld %lld",&vz[i].first,&vz[i].second);
        LL res=0;
        for(int i=n;i>=1;--i){
            it = dp1.lower_bound(vz[i].X);
            if(it==dp1.begin()||dp1.empty()){
                res += vz[i].first;
            }
            else{
                --it;
                res += vz[i].X - (*it);
            }
            it = dp2.lower_bound(vz[i].Y);
            if(it==dp2.begin()||dp2.empty()){
                res += vz[i].second;
            }
            else{
                --it;
                res += vz[i].Y - (*it);
            }
            dp1.insert(vz[i].first);
            dp2.insert(vz[i].second);
        }
        printf("%lld\n",res);
    }
    return 0;
}

ACM-ICPC 2018 徐州賽區網絡預賽 G. Trace (set維護)