题目链接
Code
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;
#define RG register int
#define LL long long
template<typename elemType>
inline void Read(elemType &T){
elemType X=0,w=0; char ch=0;
while(!isdigit(ch)) {w|=ch=='-';ch=getchar();}
while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
T=(w?-X:X);
}
const int maxn=100010;
inline int lowbit(int x){return x&(-x);}
struct BIT{
int Node[300010];
int N;
void set_Len(int len){N=len;}
void Update(int x,int Add){for(;x<=N;x+=lowbit(x)) Node[x]+=Add;}
int PrefixSum(int x){int Res=0;for(;x;x-=lowbit(x)) Res+=Node[x];return Res;}
};
BIT Tree;
struct Point{int a,b,c;};
Point Data[maxn];
int ID[maxn],Count[maxn],temp[maxn],Cnt[maxn],Ans[maxn];
int N,K,top;
bool cmp(int x,int y){
if(Data[x].a==Data[y].a){
if(Data[x].b==Data[y].b) return Data[x].c<Data[y].c;
return Data[x].b<Data[y].b;
}
return Data[x].a<Data[y].a;
}
void CDQ(int *id,int n){
if(n==1) return;
int mid=n>>1;
CDQ(id,mid);
CDQ(id+mid,n-mid);
memcpy(temp+1,id+1,n*sizeof(int));
RG k=1,i=1,j=mid+1;
for(;i<=mid && j<=n;++k){
int x=temp[i],y=temp[j];
if(Data[x].b<=Data[y].b){Tree.Update(Data[id[k]=x].c,Count[x]);++i;}
else{Cnt[y]+=Tree.PrefixSum(Data[id[k]=y].c);++j;}
}
--k;
for(;j<=n;++j){
Cnt[temp[j]]+=Tree.PrefixSum(Data[temp[j]].c);
id[++k]=temp[j];
}
for(RG l=i-1;l>=1;--l)
Tree.Update(Data[temp[l]].c,-Count[temp[l]]);
for(;i<=mid;++i) id[++k]=temp[i];
return;
}
void Unique(){
sort(ID+1,ID+N+1,cmp);
top=1;Count[ID[top]]=1;
for(RG i=2;i<=N;++i){
int x=ID[i],y=ID[top];
if(Data[x].a^Data[y].a||Data[x].b^Data[y].b||Data[x].c^Data[y].c){
ID[++top]=x;++Count[x];}
else ++Count[ID[top]];
}
return;
}
int main(){
Read(N);Read(K);
Tree.set_Len(K);
for(RG i=1;i<=N;++i){
ID[i]=i;
Read(Data[i].a);
Read(Data[i].b);
Read(Data[i].c);
}
Unique();
CDQ(ID,top);
for(RG i=1;i<=top;++i)
Ans[Cnt[ID[i]]+Count[ID[i]]-1]+=Count[ID[i]];
for(RG i=0;i<N;++i)
printf("%d\n",Ans[i]);
return 0;
}