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
CDQ分治。先按照x排序。然后我们用归并排序的方法排序y。同时把z放进树状数组
因为x排序好了。所以归并的时候保证左半边的x小于等于右半边。那么我们只需要在放入右半边数的时候记录有几个z比它小就可以了
【果然状态不行各种傻逼错调了好久】
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
using namespace std;
struct number
{
int x,y,z;
int p;
int s;
}a[100001],b[100001],c[100001];
int rank[100001];
int sx[100001];
inline bool cmpx(number x,number y)
{
if(x.x<y.x)
return true;
if(x.x==y.x)
{
if(x.y<y.y)
return true;
if(x.y==y.y)
if(x.z<y.z)
return true;
}
return false;
}
int tr[200001];
int k;
inline int lowbit(int x)
{
return x&(-x);
}
inline void add(int x,int xx)
{
int i;
for(i=x;i<=k;i+=lowbit(i))
tr[i]+=xx;
}
inline int ask(int x)
{
int i;
int ans=0;
for(i=x;i>=1;i-=lowbit(i))
ans+=tr[i];
return ans;
}
inline void solve(int l,int r)
{
int mid=(l+r)/2;
if(l!=r)
{
solve(l,mid);
solve(mid+1,r);
int i1=l,i2=mid+1;
int p=0;
//memset(tr,0,sizeof(tr));
while(i1<=mid&&i2<=r)
{
if(a[i1].y<=a[i2].y)
{
p++;
c[p]=a[i1];
add(c[p].z,c[p].s);
i1++;
}
else
{
p++;
c[p]=a[i2];
rank[c[p].p]+=ask(c[p].z);
i2++;
}
}
if(i1<=mid)
{
int i;
for(i=i1;i<=mid;i++)
{
p++;
c[p]=a[i];
add(c[p].z,c[p].s);
}
}
else if(i2<=r)
{
int i;
for(i=i2;i<=r;i++)
{
p++;
c[p]=a[i];
rank[c[p].p]+=ask(c[p].z);
}
}
int i;
for(i=l;i<=mid;i++)
add(a[i].z,-a[i].s);
for(i=l;i<=r;i++)
a[i]=c[i-l+1];
}
}
int main()
{
// freopen("test.in","r",stdin);
// freopen("test.out","w",stdout);
int n;
scanf("%d%d",&n,&k);
int i;
for(i=1;i<=n;i++)
{
scanf("%d%d%d",&b[i].x,&b[i].y,&b[i].z);
b[i].p=i;
}
sort(b+1,b+1+n,cmpx);
int t=0;
for(i=1;i<=n;i++)
{
if(b[i].x!=b[i-1].x||b[i].y!=b[i-1].y||b[i].z!=b[i-1].z)
{
t++;
a[t]=b[i];
a[t].s=1;
a[t].p=t;
}
else
a[t].s++;
}
for(i=1;i<=t;i++)
b[i]=a[i];
solve(1,t);
//for(i=1;i<=t;i++)
// printf("%d\n",rank[i]);
for(i=1;i<=t;i++)
sx[rank[i]+b[i].s]+=b[i].s;
for(i=1;i<=n;i++)
printf("%d\n",sx[i]);
return 0;
}