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的最小值即可。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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\n",ans); 54 } 55 return 0; 56 }