题意:
有n个程序员,每个程序员有三个能力值,当一个程序员三个能力值都小于另外一个程序员的时候,那么就可以淘汰那个程序员,问经过淘汰之后,还剩下几个程序员。
思路:
我们首先按照x排序,那么我们就只需要考虑y,z的情况了,这个时候可以用线段树,我们以y作为区间,以z作为值,每次查询只需要看1~y-1区间内是否已经存在小于z的值,如果存在,那么这个人就要淘汰
#include <iostream> #include <stdio.h> #include <string.h> #include <stack> #include <queue> #include <map> #include <set> #include <vector> #include <math.h> #include <bitset> #include <algorithm> #include <climits> using namespace std; #define ls 2*i #define rs 2*i+1 #define UP(i,x,y) for(i=x;i<=y;i++) #define DOWN(i,x,y) for(i=x;i>=y;i--) #define MEM(a,x) memset(a,x,sizeof(a)) #define W(a) while(a) #define gcd(a,b) __gcd(a,b) #define LL long long #define ULL unsigned long long #define N 100005 #define INF 0x3f3f3f3f #define EXP 1e-8 #define rank rank1 const int mod = 1000000007; int n,t; struct node { int x,y,z; } a[N]; int s[N<<2]; int cmp(node a,node b) { return a.x<b.x; } void pushup(int i) { s[i] = min(s[ls],s[rs]); } void updata(int l,int r,int i,int pos,int val) { if(l == r) { s[i] = val; return; } int mid = (l+r)/2; if(pos<=mid) updata(l,mid,ls,pos,val); else updata(mid+1,r,rs,pos,val); pushup(i); } int query(int L,int R,int l,int r,int i) { if(L<=l&&r<=R) { return s[i]; } int mid = (l+r)/2,minn = INF; if(L<=mid) minn = min(minn,query(L,R,l,mid,ls)); if(R>=mid+1) minn = min(minn,query(L,R,mid+1,r,rs)); return minn; } int main() { scanf("%d",&t); while(t--) { MEM(s,INF); int i; scanf("%d",&n); for(i = 0; i<n; i++) scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z); sort(a,a+n,cmp); int ans = 0; for(i = 0; i<n; i++) { if(a[i].y!=1) { int tem = query(1,a[i].y-1,1,n,1); if(tem<a[i].z) continue; } ans++; updata(1,n,1,a[i].y,a[i].z); } printf("%d\n",ans); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-10-12 21:24:54