[ACM Day2] E.Excellet Engineers

题目描述

You are working for an agency that selects the best software engineers from Belgium, the Netherlands and Luxembourg for employment at various international companies. Given the very large number of excellent software engineers these countries have to offer, the agency has charged you to develop a tool that quickly selects the best candidates available from the agency’s files.
Before a software engineer is included in the agency’s files, he has to undergo extensive testing. Based on these tests, all software engineers are ranked on three essential skills: communication skills, programming skills, and algorithmic knowledge. The software engineer with rank one in the category algorithmic knowledge is the best algorithmic expert in the files, with rank two the second best, etcetera.
For potential customers, your tool needs to process the agency’s files and produce a shortlist of the potentially most interesting candidates. A software engineer is a potential candidate that is to be put on this shortlist if there is no other software engineer in the files that scores better on all three skills. That is, an engineer is to be put on the shortlist if there is no other software engineer that has better communication skills, better programming skills, and more algorithmic knowledge.
简单化成中文来讲,就是每个人有三个排名x,y,z,如果一个人三个排名都小于某个人,那么他就没有被选中的必要,求有多少个人落选。

数据范围

T<=100N<=100000 T <= 100 N <= 100000

分析

第一眼看到这道题,就感觉是数据结构题,但开始做时发现有三维,首先根据 x x 排序可以少掉一维,然后以y作为线段树下标, z z <script type="math/tex" id="MathJax-Element-70">z</script>作为维护的值,那么问题就解决了。

#include <bits/stdc++.h>
#define rep( i , l , r ) for( int i = (l) ; i <= (r) ; ++i )
#define per( i , r , l ) for( int i = (r) ; i >= (l) ; --i )
#define erep( i , u ) for( int i = head[(u)] ; ~i ; i = e[i].nxt )
using namespace std;
int _read(){
    char ch = getchar();
    int x = 0 , f = 1 ;
    while( !isdigit( ch ) )
           if( ch == '-' ) f = -1 , ch = getchar();
           else ch = getchar();
    while( isdigit( ch ) )
           x = (ch  - '0') + x * 10 , ch =  getchar();
    return x * f;
}
const int INF = 0x7f7f7f7f;
const int maxn = 1e5 + 10;
struct segnode{
    int l , r;
    int v;
    segnode *lc, *rc;
} pool[maxn * 4] , *tail = pool;
inline segnode* newnode(){ return tail++; }
inline int _min( int a , int b ){ return a > b ? b : a; }
void build( int l , int r , segnode *rt ){
    rt->l = l , rt->r = r;
    if( l == r ){
        rt->v = INF;
        rt->lc = rt->rc = NULL;
        return;
    }
    int mid = (l + r) >> 1;
    build( l , mid , rt->lc = newnode() );
    build( mid + 1 , r , rt->rc = newnode() );
    rt->v = _min( rt->lc->v , rt->rc->v );
}
void modify( int pos , int v , segnode *rt ){
    if( rt->l == rt->r ){
        rt->v = v;
        return;
    }
    int mid = (rt->l + rt->r) >> 1;
    if( pos <= mid ) modify( pos , v , rt->lc );
    else modify( pos , v , rt->rc );
    rt->v = _min( rt->lc->v , rt->rc->v );
}
int query( int ql , int qr , segnode *rt ){
    if( ql <= rt->l && rt->r <= qr ){
        return rt->v;
    }
    int mid = (rt->l + rt->r) >> 1 , ret = INF;
    if( qr > mid ) ret = _min( ret , query( ql , qr , rt->rc ) );
    if( ql <= mid ) ret = _min( ret , query( ql , qr , rt->lc ) );
    return ret;
}
struct node{
    int x , y , z;
}A[maxn];
inline bool cmp( node a , node b ){
    return a.x < b.x;
}
int main(){
    int T = _read() , N;
    while( T-- ){
        tail = pool;
        N = _read();
        rep( i , 1 , N )
            A[i].x = _read() , A[i].y = _read() , A[i].z = _read();
        sort( A + 1 , A + N + 1 , cmp );
        segnode *root = newnode();
        build( 1 , N , root );
        int ans = 0;
        rep( i , 1 , N ){
            if( A[i].y != 1 ){
                int t = query( 1 , A[i].y - 1 , root );
                if( A[i].z > t ) continue;
            }
            ans++;
            modify( A[i].y , A[i].z , root );
        }
        cout << ans << endl;
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值