您的位置:首页 > 其它

bzoj 3262 陌上花开

2016-12-10 13:57 295 查看
本质是一个三维偏序,一位排序后cdq分治,一维在子函数里排序,一维用树状数组维护。

把三维相等的合并到一个里面。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define N 100005
using namespace std;
int n,k,m;
struct node
{
int x,y,z,num,op;
int yuan;
bool operator == (const node &b)
{
return x==b.x&&y==b.y&&z==b.z;
}
}a
,b
;
int shan
;
int ans
;
bool cmp1(node aa,node bb)
{
if(aa.num==0)return 0;
if(bb.num==0)return 1;
if(aa.x!=bb.x)return aa.x<bb.x;
if(aa.y!=bb.y)return aa.y<bb.y;
if(aa.z!=bb.z)return aa.z<bb.z;

}
bool cmp2(node aa,node bb)
{
if(aa.y!=bb.y)return aa.y<bb.y;
return aa.op<bb.op;
}
int c[200005];
void add(int x,int y)
{
for(int i=x;i<=k;i+=(i&(-i)))c[i]+=y;
}
int qur(int x)
{
int now=0;
for(int i=x;i;i-=(i&(-i)))now+=c[i];
return now;
}
void solve(int l,int r)
{
if(l==r)return ;
int mid=(l+r)>>1;
solve(l,mid);solve(mid+1,r);
int cnt=0;
for(int i=l;i<=mid;i++)
{
b[++cnt]=a[i];
b[cnt].op=1;
}
for(int i=mid+1;i<=r;i++)
{
b[++cnt]=a[i];
b[cnt].op=2;
}
sort(b+1,b+cnt+1,cmp2);
for(int i=1;i<=cnt;i++)
{
if(b[i].op==1)add(b[i].z,b[i].num);
else ans[b[i].yuan]+=qur(b[i].z);
}
for(int i=1;i<=cnt;i++)if(b[i].op==1)add(b[i].z,-b[i].num);
}
int zui
;
int main()
{
scanf("%d%d",&n,&k);m=n;
for(int i=1;i<=n;i++)
{
scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);
a[i].num=1;
}
sort(a+1,a+n+1,cmp1);
for(int i=1;i<=n;i++)
{
if(a[i]==a[i-1])
{
a[shan[i-1]].num++;
shan[i]=shan[i-1];
a[i].num--;
}
else shan[i]=i;
}
sort(a+1,a+n+1,cmp1);
while(a
.num==0)n--;
for(int i=1;i<=n;i++)a[i].yuan=i;
solve(1,n);
for(int i=1;i<=n;i++)zui[ans[a[i].yuan]+a[i].num-1]+=a[i].num;
for(int i=0;i<=m-1;i++)printf("%d\n",zui[i]);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: