BZOJ3262

来自蒟蒻XXJ的做题记录

三维偏序

一维排序 二维cdq 三维树状数组

#include<bits/stdc++.h>
using namespace std;
const int MAXK=200010;
const int MAXN=100010;
inline int in(){
	int a(0);char c=getchar();
	while(c<'0'||c>'9') c=getchar();
	while(c>='0'&&c<='9') a=(a<<1)+(a<<3)+c-'0',c=getchar();
	return a;
}
int n,k;
struct Flo{
	int a,b,c,s,ans;
	bool operator < (const Flo B) const{
		if(b==B.b) return c<B.c;
		return b<B.b;
	}
}a[MAXN],p[MAXN];
int tot,answer[MAXN];
bool cmp(Flo x,Flo y){
	if(x.a==y.a&&x.b==y.b) return x.c<y.c;
	if(x.a==y.a) return x.b<y.b;
	return x.a<y.a;
}
int tree[MAXK];
void change(int pos,int quan){
	for(int i=pos;i<=k;i+=(i&-i)) tree[i]+=quan;
}
int query(int pos){
	int res(0);
	for(int i=pos;i;i-=(i&-i)) res+=tree[i];
	return res;
}
void solve(int l,int r){
	if(l==r) return;
	int mid=(l+r)>>1;
	solve(l,mid);
	solve(mid+1,r);
	sort(p+l,p+mid+1);
	sort(p+mid+1,p+r+1);
	int i=l,j=mid+1;
	while(j<=r){
		while(i<=mid&&p[i].b<=p[j].b){
			change(p[i].c,p[i].s);
			++i;
		}
		p[j].ans+=query(p[j].c);
		j++;
	}
	for(int ii=l;ii<i;ii++) change(p[ii].c,-p[ii].s);
}
void input(){
	n=in();k=in();
	for(int i=1;i<=n;i++){
		a[i].a=in();a[i].b=in();a[i].c=in();	
	}
	sort(a+1,a+n+1,cmp);
	int cnt(0);
	for(int i=1;i<=n;i++){
		++cnt;
		if(a[i].a!=a[i+1].a||a[i].b!=a[i+1].b||a[i].c!=a[i+1].c){
			p[++tot]=a[i];p[tot].s=cnt;p[tot].ans=0;
			cnt=0;
		}
	}
}
void xxj(){
	solve(1,tot);
	for(int i=1;i<=tot;i++) answer[p[i].ans+p[i].s-1]+=p[i].s;
}
void output(){
	for(int i=0;i<n;i++) cout<<answer[i]<<endl;
}

int main(){
	input();
	xxj();
	output();
	return 0;
}
posted @ 2017-03-27 10:09  Xiaojian_xiang  阅读(109)  评论(0编辑  收藏  举报