题意:
有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;
}