二维偏序入门

一维sort;

多维cdq学不会;

那就学二维吧。

二维偏序:二维偏序就可以看作是一个坐标轴中的点(x,y)就是查找有多少个点x,y都比该点小。

一般都是排序一维,另一维树状数组更新维护

例题1:http://poj.org/problem?id=2352

POJ 2352 Stars

题意:给你N个坐标然后问你每个坐标的等级(等级的意思就是X,Y都小于当前(X,Y)的坐标个数);

题解:输入的样例是默认按照先以X递增排序,再按Y递增排序给的,即默认优先按Y排序的,那么可以看成所有小于Y的坐标集合里找小于X的。枚举Y(其实没有,相当于),树状数组维护X,插入X,查询前缀和。

#include
#include
#include
#include
#include
#include
using namespace std;
const int inf=0x3f3f3f3f;
const int maxn=1000000;
struct node{
	int x,y;
}s[maxn];
int c[maxn],n;
int lowbit(int x){
  return x&-x; }
void add(int id,int p){
	while(id<=32005){
		c[id]+=p;
		id+=lowbit(id);
	}
}
int sum(int id){
	int ans=0;
	while(id>=1){
		ans+=c[id];
		id-=lowbit(id);
	}
	return ans;
}
int ans[maxn];
int main(){
	//cin>>n; 
	while(~scanf("%d",&n)){
	for(int i=1;i<=n;i++){
	//	cin>>s[i].x>>s[i].y;
    	scanf("%d%d",&s[i].x,&s[i].y);
		c[i]=0;
		ans[i]=0;
	}
    for(int i=1;i<=n;i++){
    	int x=s[i].x;
    	x++;//这里是因为坐标可以为0,但树状数组维护的时候下标从要1开始
    	ans[sum(x)]++;
    	add(x,1);
	}
	for(int i=0;i

例题2:https://ac.nowcoder.com/acm/contest/16/A Laptop

题意:N对数,每对数都代表电脑的内存价格和硬盘速度,问你有多少个电脑的这对数据都比某些电脑小

题解:这对属性看成 坐标,就是问你要多少个坐标的X,Y都小于某些坐标的X,Y;

           然后就是对X排序,树状数组维护Y,对X倒着维护Y,查询后缀和,就是说从最大的X依次插入对应的Y,就可以知道比当前I的X大的这些坐标中有多少Y是小于当前I的Y的,再用所有大于当前I的X的坐标减去查询的数若!=0,则说明确实有坐标的X,Y都大于当前I的X,Y。

#include
#include
#include
#include
#include
#include
#include
using namespace std;
const int inf=0x3f3f3f3f;
const int maxn=1e5+5;
struct node{
	int x,y;
}s[maxn];
int c[maxn],n;
int lowbit(int x){
  return x&-x; 
}
void add(int id,int p){
	while(id<=n){
		c[id]+=p;
		id+=lowbit(id);
	}
}
int sum(int id){
	int ans=0;
	while(id>=1){
		ans+=c[id];
		id-=lowbit(id);
	}
	return ans;
}
bool cmp(node a,node b){
	return a.xv;
int getid(int x){
	return lower_bound(v.begin(),v.end(),x)-v.begin()+1;
}
int main(){
    scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%d%d",&s[i].x,&s[i].y);
		v.push_back(s[i].y);
	}
	sort(v.begin(),v.end());
	v.erase(unique(v.begin(),v.end()),v.end());
	sort(s+1,s+1+n,cmp);
	int ans=0;
	for(int i=n;i>=1;i--){
		int k=getid(s[i].y);
		cout<

 

你可能感兴趣的:(树状数组)