1. 程式人生 > >Newcoder 16 A.Laptop(逆序對-BIT)

Newcoder 16 A.Laptop(逆序對-BIT)

Description

F S T FST 是一名可憐的小朋友,他很強,但是經常 f s t

fst ,所以 r a t i n g rating
一直低迷。

但是重點在於,他非常適合 A C M ACM !並在最近的區域賽中獲得了不錯的成績。

拿到獎金後 F S T

FST 決定買一臺新筆記本,但是 F S T FST 發現,在價格能承受的範圍內,筆記本的記憶體和速度是不可兼得的。

可是,有一些筆記本是被另外一些“完虐”的,也就是記憶體和速度都不高於另外某一個筆記本,現在 F S T FST 想統計一下有多少筆記本被“完虐”。

Input

第一行一個正整數 n n ,表示筆記本的數量。接下來 n n 行,每行兩個正整數 M i S i M_i,S_i 表示這款筆記本的記憶體和速度。

( n 1 0 5 , M i , S i 1 0 9 ) (n\le 10^5,M_i,S_i\le 10^9)

Output

一行,一個正整數,表示被完虐的筆記本數。

Sample Input

4
100 700
200 500
50 100
300 400

Sample Output

1

Solution

正序對,把所有筆記本按第一維降序排序後,以此將其第二維插入樹狀陣列中,對於第 i i 個筆記本,之前考慮的 i 1 i-1 個筆記本第一維比它第一維要大,如果次數樹狀陣列中它第二維所在位置之前沒有 i 1 i-1 個位置有值,說明之前至少有一個筆記本第二維也比它大,那麼這個筆記本就被完虐,以此統計答案即可,時間複雜度 O ( n l o g n ) O(nlogn)

Code

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef pair<int,int>P;
const int maxn=100005;
struct BIT 
{
	#define lowbit(x) (x&(-x))
	int b[maxn],n;
	void init(int _n)
	{
		n=_n;
		for(int i=1;i<=n;i++)b[i]=0;
	}
	void update(int x,int v)
	{
		while(x<=n)
		{
			b[x]+=v;
			x+=lowbit(x);
		}
	}
	int query(int x)
	{
		int ans=0;
		while(x)
		{
			ans+=b[x];
			x-=lowbit(x);
		}
		return ans;
	}
}bit;
P a[maxn];
int n,h[maxn],vis[maxn]; 
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		scanf("%d%d",&a[i].first,&a[i].second);
		a[i].first*=-1;
		h[i]=a[i].second;
	}
	sort(a+1,a+n+1);
	sort(h+1,h+n+1);
	bit.init(n);
	int ans=0;
	for(int i=1;i<=n;i++)
	{
		int t=lower_bound(h+1,h+n+1,a[i].second)-h;
		if(bit.query(t)!=i-1)ans++;
		bit.update(t,1);
	} 
	printf("%d\n",ans);
	return 0;
}