【牛客网】牛客练习赛4 A Laptop【树状数组+离散化】

传送门: https://www.nowcoder.com/acm/contest/16/A

在找关于 CDQ 分治道题,找到下面这条博客。
二维偏序问题

题意:

N个对象,每个对象有2个值,求有多少对象的2个值均小于其他某一个对象

思路:

等价于s,w为二维坐标x,y。
首先把s按升序排列。
离散化w。
倒着枚举s,然后查询w的后缀和不为0即为一个答案。

AC Code

#include <cstdio>
#include <iostream>
#include <algorithm>
#define lowbit(x) x&-x
#define il inline
using namespace std;
const int maxm=1e5+100;
int sum[maxm];
struct node
{
	int x,y;
} a[maxm];
int w[maxm];
il void ins(int x)
{
	for(int i=x; i<=maxm; i+=lowbit(i))
		sum[i]++;
}
il int ask(int x)
{
	int ans=0;
	for(int i=x; i; i-=lowbit(i))
		ans+=sum[i];
	return ans;
}
il bool comp(node x,node y)
{
	return x.x<y.x;
}
int main()
{
	int n;
	scanf("%d",&n);
	for(int i=1; i<=n; i++)
		scanf("%d%d",&a[i].x,&a[i].y),w[i]=a[i].y;
	sort(w+1,w+n+1);
	int t=unique(w+1,w+n+1)-w-1;

	// cout<<t<<endl;	
	for(int i=1; i<=n; i++)
		a[i].y=lower_bound(w+1,w+t+1,a[i].y)-w;
	/*
	for(int i=1;i<=n;i++)
		cout<<a[i].y<<" ";
	cout<<endl;
	*/
	sort(a+1,a+n+1,comp);
	int ans=0;
	for(int i=n; i>=1; i--)
	{
		int d=ask(a[i].y);
		//cout<<d<<endl;
		// n-i 表示可能的最多的完虐的数的数量
		// d 表示当前有几个数比他小
		if(n-i-d!=0) ans++;
		ins(a[i].y);
	}
	return printf("%d",ans)*0;
}

原文地址:https://www.cnblogs.com/shengwang/p/9838637.html