题目描述
FST是一名可怜的小朋友,他很强,但是经常fst,所以rating一直低迷。
但是重点在于,他非常适合ACM!并在最近的区域赛中获得了不错的成绩。
拿到奖金后FST决定买一台新笔记本,但是FST发现,在价格能承受的范围内,笔记本的内存和速度是不可兼得的。
可是,有一些笔记本是被另外一些“完虐”的,也就是内存和速度都不高于另外某一个笔记本,现在FST想统计一下有多少笔记本被“完虐”。
输入描述:
第一行一个正整数n,
表示笔记本的数量。接下来n行,每行两个正整数Mi,Si表示这款笔记本的内存和速度。
n≤105,Mi,Si≤109
输出描述:
一行,一个正整数,表示被完虐的笔记本数。
输入
4
100 700
200 500
50 100
300 400
输出
1
大致思路:
对于每一个笔记本都有两个值,先对于任意一个值进行排序。
然后建立线段树,统计区间另一个最大值。
然后从后往前扫,每次扫描当前位置到最后一个的区间之内有没有比另一个值大的,如果有ans++
代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int INF=1<<30; 4 const int maxn=1e5+7; 5 struct Node{ 6 int m,s; 7 }node[maxn]; 8 int tree[maxn<<2]; 9 void build(int l,int r,int k) 10 { 11 //cout<<k<<endl; 12 if(l>r) 13 return ; 14 if(l==r){ 15 tree[k]=node[l].s; 16 return ; 17 } 18 int mid=(l+r)>>1; 19 build(l,mid,k<<1); 20 build(mid+1,r,k<<1|1); 21 tree[k]=max(tree[k<<1],tree[k<<1|1]); 22 } 23 int query(int l,int r,int ql,int qr,int k) 24 { 25 if(l>r||ql>r||qr<l) 26 return -INF; 27 if(ql<=l&&qr>=r) 28 return tree[k]; 29 int mid=(l+r)>>1; 30 return max(query(l,mid,ql,qr,k<<1),query(mid+1,r,ql,qr,k<<1|1)); 31 } 32 bool cmp(Node a,Node b) 33 { 34 return a.m<b.m; 35 } 36 int main() 37 { 38 //freopen("in.txt","r",stdin); 39 ios::sync_with_stdio(false); 40 memset(tree,0,sizeof(tree)); 41 int n,ans=0; 42 cin>>n; 43 for(int i=0;i<n;++i) 44 cin>>node[i].m>>node[i].s; 45 sort(node,node+n,cmp); 46 build(0,n-1,1); 47 for(int i=n-2;i>=0;--i){ 48 int x=query(0,n-1,i,n-1,1);//区间查询 49 //cout<<x<<" "<<i<<endl; 50 if(x>node[i].s) 51 ans++; 52 } 53 cout<<ans<<endl; 54 return 0; 55 }