2015 Benelux Algorithm Programming Contest E-Excellent Engineers

题目大意:有n个人,每个人都有三个物品,排名分别为a[ i ],b[ i ],b[ i ],现在要删掉其中的一些人

如果一个人x的三个物品的排名为a[ x ],b[ x ],b[ x ],若存在另一个人y物品排名为a[ y ],b[ y ],b[ y ],

且a[ y ]<a[ x ] && b[ y ]<b[ x ]  && c[ y ]<c[ x ],则删掉x,问你最后剩下多少人。

思路:一开始肯定要按一个物品的排名进行排序,然后就三个人想了半小时没想出来,感觉要用数据

结构,但是不知道怎么写,看来还是对线段树不太了解!!!!

首先,我们按物品a的排名排序,然后我们用b物品的排名建立线段树维护物品c的最小值即可。

 1 #include<bits/stdc++.h>
 2 #define lson l,m,rt<<1
 3 #define rson m+1,r,rt<<1|1
 4 using namespace std;
 5 const int N=1e5+5;
 6 const int inf=0x3f3f3f3f;
 7 int mn[N<<2],n;
 8 struct node
 9 {
10     int a,b,c;
11     bool operator <(const node &t)const
12     {
13         return a<t.a;
14     }
15 }w[N];
16 void updata(int x,int v,int l,int r,int rt)
17 {
18     if(l==r)
19     {
20         mn[rt]=min(mn[rt],v);
21         return;
22     }
23     int m=(l+r)>>1;
24     if(x<=m) updata(x,v,lson);
25     else updata(x,v,rson);
26     mn[rt]=min(mn[rt<<1],mn[rt<<1|1]);
27 }
28 int query(int L,int R,int l,int r,int rt)
29 {
30     if(l>=L && r<=R) return mn[rt];
31     int m=(l+r)>>1;
32     int ans=inf;
33     if(L<=m) ans=min(ans,query(L,R,lson));
34     if(R>m) ans=min(ans,query(L,R,rson));
35     return ans;
36 }
37 int main()
38 {
39     int T; cin>>T;
40     while(T--)
41     {
42         cin>>n;
43         for(int i=0;i<n;i++) scanf("%d%d%d",&w[i].a,&w[i].b,&w[i].c);
44         sort(w,w+n);
45         memset(mn,inf,sizeof(mn));
46         int ans=0;
47         for(int i=0;i<n;i++)
48         {
49             int g=query(1,w[i].b,1,n,1);
50             if(g>w[i].c) ans++;
51             updata(w[i].b,w[i].c,1,n,1);
52         }
53         printf("%d
",ans);
54     }
55     return 0;
56 }
View Code
原文地址:https://www.cnblogs.com/CJLHY/p/7610700.html