BZOJ3262: 陌上花开

众所周知三维偏序可以树套树或者分治

然后我就写了二维离散化+二维树状数组

然而并没有分治快……

#include<algorithm>
#include<cstdio>
#define F lower_bound
#define G upper_bound
using namespace std;
const int N=1e5+5;
struct buf{
	operator int(){
		int x;scanf("%d",&x);
		return x;
	}
}it;
struct vec{int i,j,k;}s[N];
bool operator<(vec a,vec b){
	return a.i^b.i?a.i<b.i:a.j^b.j?a.j<b.j:a.k<b.k;
}
bool operator!=(vec a,vec b){
	return a<b||b<a;
}
int e[N*40],*q=e;
struct node{
	int sum(int i){
		int j=0;
		for(i=G(u,u+s,i)-u;i;i^=i&-i)
			j+=v[i-1];
		return j;
	}
	void add(int i){
		for(i=G(u,u+s,i)-u;i<=s;i+=i&-i)
			++v[i-1];
	}
	int s,*u,*v;
	void alloc(){
		u=q,q+=s,v=q,q+=s,s=0;
	}
	void ins(int i){
		u[s++]=i;
	}
	void ins(node& a){
		for(int i=0;i!=a.s;++i)
			u[s++]=a.u[i];
	}
	void init(){
		sort(u,u+s);
		s=unique(u,u+s)-u;
	}
}t[N];
int n,m,l[N],v[N];
int main(){
	n=it,~it;
	for(int i=0;i!=n;++i){
		s[i].i=it;
		s[i].j=l[i]=it;
		s[i].k=it;
	}
	sort(l,l+n);
	m=unique(l,l+n)-l;
	sort(s,s+n);
	for(int i=0;i!=n;++i)
		++t[s[i].j=F(l,l+m,s[i].j)-l+1].s;
	for(int i=1;i<=m;++i){
		if(i+(i&-i)<=m)
			t[i+(i&-i)].s+=t[i].s;
		t[i].alloc();
	}
	for(int i=0;i!=n;++i)
		t[s[i].j].ins(s[i].k);
	for(int i=1;i<=m;++i){
		t[i].init();
		if(i+(i&-i)<=m)
			t[i+(i&-i)].ins(t[i]);
	}
	for(int i=0,j=-1;i!=n;++i){
		if(s[i+1]!=s[i]){
			int* u=v;
			for(int k=s[i].j;k;k^=k&-k)
				u+=t[k].sum(s[i].k);
			*u+=i-j,j=i;
		}
		for(int k=s[i].j;k<=m;k+=k&-k)
			t[k].add(s[i].k);
	}
	for(int i=0;i!=n;++i)
		printf("%d\n",v[i]);
}
posted @ 2016-08-24 16:39  f321dd  阅读(123)  评论(0编辑  收藏  举报