3262: 陌上花开
Time Limit: 20 Sec Memory Limit: 256 MB
Submit: 4087 Solved: 1932
[Submit][Status][Discuss]
Description
有n朵花,每朵花有三个属性:花形(s)、颜色(c)、气味(m),用三个整数表示。
现在要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量。
定义一朵花A比另一朵花B要美丽,当且仅Sa>=Sb,Ca>=Cb,Ma>=Mb。
显然,两朵花可能有同样的属性。需要统计出评出每个等级的花的数量。
Input
第一行为N,K (1 <= N <= 100,000, 1 <= K <= 200,000 ), 分别表示花的数量和最大属性值。
以下N行,每行三个整数si, ci, mi (1 <= si, ci, mi <= K),表示第i朵花的属性
Output
包含N行,分别表示评级为0...N-1的每级花的数量。
Sample Input
10 3
3 3 3
2 3 3
2 3 1
3 1 1
3 1 2
1 3 1
1 1 2
1 2 2
1 3 2
1 2 1
Sample Output
3
1
3
0
1
0
1
0
0
1
HINT
思路: 三维偏序关系,可以用cdq分治+树状数组维护,但是这里相同的a,b,c 会互相产生影响,所以特判一下,处理掉这种情况。
代码:
#include<bits/stdc++.h>
using namespace std;
const int N =1e5+5;
struct node
{
int a,b,c;
int id;
}aa[N],tmp[N];
int n,k;
int c[200005];
int ans[N];
int cnt[N];
bool cmp(node x,node 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 lowbit(int x)
{
return x&(-x);
}
void update(int x)
{
for(;x<=k;x+=lowbit(x)) c[x]++;
}
int query(int x)
{
int sum=0;
for(;x>0;x-=lowbit(x)) sum+=c[x];
return sum;
}
void clearr(int x)
{
for(;x<=k;x+=lowbit(x)){
if(c[x]==0) break;
c[x]=0;
}
}
void cdq(int l,int r)
{
//cout<<"l "<<l<<" r "<<r<<endl;
if(l>=r) return ;
int mid=(l+r)>>1;
cdq(l,mid);
cdq(mid+1,r);
int p,q,id;
p=l; q=mid+1; id=l;
while(p<=mid&&q<=r){
if(aa[p].b<=aa[q].b){
update(aa[p].c);
tmp[id++]=aa[p++];
}
else{
ans[aa[q].id]+=query(aa[q].c);
tmp[id++]=aa[q++];
}
}
while(p<=mid) tmp[id++]=aa[p++];
while(q<=r){
ans[aa[q].id]+=query(aa[q].c);
tmp[id++]=aa[q++];
}
for(int i=l;i<=r;i++){
clearr(aa[i].c);
aa[i]=tmp[i];
}
/*
cout<<"*** l "<<l<<" ** r "<<r<<endl;
for(int i=1;i<=n;i++) cout<<ans[i]<<" ";
cout<<endl;
*/
}
bool same(node x, node y)
{
if(x.a==y.a&&x.b==y.b&&x.c==y.c) return 1;
return 0;
}
int main()
{
scanf("%d %d",&n,&k);
for(int i=1;i<=n;i++){
//cin>>aa[i].a>>aa[i].b>>aa[i].c;
scanf("%d %d %d",&aa[i].a,&aa[i].b, &aa[i].c);
aa[i].id=i;
}
sort(aa+1,aa+n+1,cmp);
node temp=node{-1,-1,-1,-1};
int res=0;
for(int i=n;i>=1;i--){
if(same(aa[i],temp)){
ans[aa[i].id]+=res;
res++;
}
else{
temp=aa[i];
res=1;
}
}
cdq(1,n);
for(int i=1;i<=n;i++){
cnt[ans[i]]++;
}
for(int i=0;i<n;i++){
printf("%d\n",cnt[i]);
}
return 0;
}
/*
5 3
3 3 3
3 3 3
3 3 3
3 3 3
3 3 3
*/