题目:链接:https://www.nowcoder.com/acm/contest/16/A
来源:牛客网
题目描述
FST是一名可怜的小朋友,他很强,但是经常fst,所以rating一直低迷。
但是重点在于,他非常适合ACM!并在最近的区域赛中获得了不错的成绩。
拿到奖金后FST决定买一台新笔记本,但是FST发现,在价格能承受的范围内,笔记本的内存和速度是不可兼得的。
可是,有一些笔记本是被另外一些“完虐”的,也就是内存和速度都不高于另外某一个笔记本,现在FST想统计一下有多少笔记本被“完虐”。
输入描述:
第一行一个正整数n, 表示笔记本的数量。接下来n行,每行两个正整数Mi,Si表示这款笔记本的内存和速度。 n≤105,Mi,Si≤109
输出描述:
一行,一个正整数,表示被完虐的笔记本数。
示例1
输入
复制
4 100 700 200 500 50 100 300 400
输出
复制
1
备注:
Mi和Si都是越大越优。 数据保证Mi互不相同,Si也互不相同。
一道贪心+线段树的题目
解题思路:先按照电脑的某一个价值排序,之后对另一个价值进行线段树排序,在倒序的前题下,来判断在某点后边 是不是有线段树排序的价值比它大的。emmmm,说的可能有点难懂,上代码
ac代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define maxn 500005
using namespace std;
struct node{
int m,s;
}com[maxn];
int tree[maxn];
bool cmp(node a,node b)
{
return a.m<b.m;
}
void pushup(int cur)
{
tree[cur]=max(tree[cur<<1],tree[cur<<1|1]);
}
void build(int l,int r,int cur)
{
if(l>r) return ;
if(l==r)
{
tree[cur]=com[l].s;
return ;
}
int m=(l+r)>>1;
build(l,m,cur<<1);
build(m+1,r,cur<<1|1);
pushup(cur);
}
int queryll(int l,int r,int lt,int rt,int cur)
{
if(lt>rt||r<lt||l>rt)
return -999999;
if(lt>=l&&rt<=r)
return tree[cur];
int m=(lt+rt)>>1;
return max(queryll(l,r,lt,m,cur<<1),queryll(l,r,m+1,rt,cur<<1|1));
}
int main()
{
int n;
memset(tree,0,sizeof(tree));
cin>>n;
int ans=0;
for(int i=1;i<=n;i++)
cin>>com[i].m>>com[i].s;
sort(com+1,com+1+n,cmp);
build(1,n,1);
for(int i=n-1;i>0;i--)
{
int x=queryll(i,n,1,n,1);
if(x>com[i].s)
ans++;
}
cout<<ans<<endl;
return 0;
}