第一维排序,剩下两维用CDQ分治
3262: 陌上花开
Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 475 Solved: 216
[ 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
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
1
3
0
1
0
1
0
0
1
HINT
1 <= N <= 100,000, 1 <= K <= 200,000
Source
/* ***********************************************
Author :CKboss
Created Time :2015年08月02日 星期日 16时32分58秒
File Name :BZOJ3262_2.cpp
************************************************ */
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <cmath>
#include <cstdlib>
#include <vector>
#include <queue>
#include <set>
#include <map>
using namespace std;
const int maxn=200200;
/*************BIT******************/
int tree[maxn],color[maxn],C;
inline int lowbit(int x) { return x&(-x); }
void Add(int p,int v)
{
for(int i=p;i<maxn;i+=lowbit(i))
{
if(color[i]!=C) tree[i]=0;
color[i]=C;
tree[i]+=v;
}
}
int Sum(int p)
{
int ret=0;
for(int i=p;i;i-=lowbit(i))
{
if(color[i]==C)
ret+=tree[i];
}
return ret;
}
/****************NODE**************/
int n,S;
struct Flower
{
int a,b,c,level,num;
void toString()
{
printf("(%d,%d,%d) level: %d num: %d\n",a,b,c,level,num);
}
}flower[maxn];
bool cmp(Flower a,Flower b){
if (a.a==b.a && a.b==b.b) return a.c<b.c;
if (a.a==b.a) return a.b<b.b;
return a.a<b.a;
}
bool cmpCDQ(Flower a,Flower b){
if (a.b==b.b) return a.c<b.c;
return a.b<b.b;
}
/***************CDQ****************/
void CDQ(int left,int right)
{
if(left==right) return ;
int mid=(left+right)/2;
CDQ(left,mid);CDQ(mid+1,right);
sort(flower+left,flower+mid+1,cmpCDQ);
sort(flower+mid+1,flower+right+1,cmpCDQ);
int i,j;C++;
for(j=mid+1,i=left;j<=right;j++)
{
for(;flower[i].b<=flower[j].b&&i<=mid;i++)
Add(flower[i].c,flower[i].num);
flower[j].level+=Sum(flower[j].c);
}
}
int ans[maxn];
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
scanf("%d%d",&n,&S);
for(int i=1,a,b,c;i<=n;i++)
{
scanf("%d%d%d",&a,&b,&c);
flower[i]=(Flower){a,b,c,0,1};
}
sort(flower+1,flower+n+1,cmp);
int tot=1;
for(int i=2;i<=n;i++)
{
if(flower[i].a!=flower[tot].a
||(flower[i].b!=flower[tot].b)
||(flower[i].c!=flower[tot].c))
{
tot++;
flower[tot]=flower[i];
}
else
{
flower[tot].num++;
}
}
CDQ(1,tot);
for(int i=1;i<=tot;i++)
ans[flower[i].level+flower[i].num-1]+=flower[i].num;
for(int i=0;i<n;i++)
printf("%d\n",ans[i]);
return 0;
}