二维偏序&三维偏序的一些总结

二维偏序

数星星 https://loj.ac/problem/10114

大概就是先按第一维排个序,然后按第二维建个树状数组,值域为下标,每次查询之前的有几个就行了(sum函数)

直接上代码



#include 

using namespace std;
const int maxn=3.2*10005;
struct node
{
	int x,y;
}a[maxn];int c[maxn];int n,cnt[maxn];
int maxv=0;
int cmp(node x,node y)
{
	if(x.x!=y.x) return x.x0)
	{
		s+=c[x];
		x-=lowbit(x);
	}
	return s;
}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		scanf("%d%d",&a[i].x,&a[i].y); 
		a[i].x+=1;a[i].y+=1;
		maxv=max(maxv,a[i].y);
		
	}
	sort(a+1,a+1+n,cmp);
	for(int i=1;i<=n;i++)
	{
		cnt[sum(a[i].y)]++;
		add(a[i].y,1);
	}
	for(int i=0;i

三维偏序

在二维的基础上加个分治就ok了。先全部按照x排序,然后进行分治。然后把每一次的答案+=到总答案里

#include 

using namespace std;
int _n,k;
const int maxn=200005;
struct node
{
	int x,y,z,ans,w;
}a[maxn],b[maxn];int n;int c[maxn]; 
int ans[maxn];
int cmp(node x,node y)
{
	if(x.x!=y.x) return x.x0)
	{
		s+=c[x];
		x-=lowbit(x);
	}
	return s;
}
void solve(int l,int r)
{
	if(l==r) return; 
	int mid=(l+r)/2;
	solve(l,mid);solve(mid+1,r);
	sort(a+l,a+mid+1,cmp1);sort(a+mid+1,a+r+1,cmp1);
	int i=mid+1;int j=l;
	for(;i<=r;i++)
	{
		while(a[j].y<=a[i].y&&j<=mid) add(a[j].z,a[j].w),j++;
		a[i].ans+=sum(a[i].z);
	}
	for(i=l;i

 

你可能感兴趣的:(数据结构)