bzoj3262:陌上花开
传送门
典型的三维偏序,cdq分治
由于相同的花之间也会产生贡献,考虑将相同的花合并来做
代码:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
void read(int &x) {
char ch; bool ok;
for(ok=0,ch=getchar(); !isdigit(ch); ch=getchar()) if(ch=='-') ok=1;
for(x=0; isdigit(ch); x=x*10+ch-'0',ch=getchar()); if(ok) x=-x;
}
#define rg register
#define lowbit(i) (i&(-i))
const int maxn=1e5+10,maxm=2e5+10;
int n,m,ans[maxn],f[maxm];
struct oo{int id,x,y,z,ans,cnt;}a[maxn];
bool cmp(oo a,oo b){return a.x==b.x?(a.y==b.y?a.z<b.z:a.y<b.y):a.x<b.x;}
bool cmp1(oo a,oo b){return a.y==b.y?a.id<b.id:a.y<b.y;}
void add(int x,int y){for(rg int i=x;i<=m;i+=lowbit(i))f[i]+=y;}
int get(int x){int ans=0;for(rg int i=x;i;i-=lowbit(i))ans+=f[i];return ans;}
void cdq(int l,int r)
{
if(l==r)return ;
int mid=(l+r)>>1;
cdq(l,mid),cdq(mid+1,r);
sort(a+l,a+r+1,cmp1);
for(rg int i=l;i<=r;i++)
if(a[i].id<=mid)add(a[i].z,1);
else a[i].ans+=get(a[i].z);
for(rg int i=l;i<=r;i++)
if(a[i].id<=mid)add(a[i].z,-1);
}
int main()
{
read(n),read(m);
for(rg int i=1;i<=n;i++)read(a[i].x),read(a[i].y),read(a[i].z);
sort(a+1,a+n+1,cmp);
for(rg int i=1;i<=n;i++)a[i].id=i;
cdq(1,n);
for(rg int i=1;i<=n;i++)ans[a[i].ans]++;
for(rg int i=0;i<n;i++)printf("%d\n",ans[i]);
}