第一维排序 第二维cdq 第三维权值线段树 本地跑不会t,但是测评全t了
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <memory.h>
#define LL long long
using namespace std;
const int N=100001;
inline int read()
{
int x=0;bool w=0;char ch=0;
while(ch<'0'|ch>'9'){w|=(ch=='-');ch=getchar();}
while(ch>='0'&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return w?-x:x;
}
struct cdq{int a,b,c,tag,cnt;cdq(){cnt=1;}}a[N],tmp[N];int ans[N];
bool cmp(int i,int j)
{
if(a[i].a==a[j].a)
{
if(a[i].b==a[j].b)return a[i].c<=a[j].c;
return a[i].b<=a[j].b;
}
return a[i].a<=a[j].a;
}
void sort_a(int l,int r)
{
if(l==r)return;int m=l+r>>1,i=l,j=m+1,tot=l;
sort_a(l,m);sort_a(m+1,r);
while(i<=m&j<=r)tmp[tot++]=(cmp(i,j)?a[i++]:a[j++]);
while(i<=m)tmp[tot++]=a[i++];
while(j<=r)tmp[tot++]=a[j++];
for(i=l;i<=r;i++)a[i]=tmp[i];
}
int sum[N<<3];
void add(int u,int l,int r,int x,int k)
{
if(l==r){sum[u]+=k;return;}
int m=l+r>>1;
if(x<=m)add(u<<1,l,m,x,k);
if(x>=m+1)add(u<<1|1,m+1,r,x,k);
sum[u]+=k;
// sum[u]=sum[u<<1]+sum[u<<1|1];
}
int query(int u,int l,int r,int x,int y)
{
if(x<=l&r<=y)return sum[u];
int m=l+r>>1;
if(y<=m)return query(u<<1,l,m,x,y);
if(x>=m+1)return query(u<<1|1,m+1,r,x,y);
return query(u<<1,l,m,x,y)+query(u<<1|1,m+1,r,x,y);
}
void testtree(int l,int r)
{
printf("%d\t%d\t%d\n",l,r,sum[1]);
}
int size;
void solve(int l,int r)
{
if(l==r)return;int m=l+r>>1,i=l,j=m+1,tot=l;solve(l,m);solve(m+1,r);
while(i<=m&j<=r)
{
if(a[i].b<=a[j].b)
{
add(1,1,size,a[i].c,a[i].cnt);tmp[tot++]=a[i++];
}
else
{
ans[a[j].tag]+=query(1,1,size,1,a[j].c);
tmp[tot++]=a[j++];
}
}
// testtree(l,r);
while(i<=m){add(1,1,size,a[i].c,a[i].cnt);tmp[tot++]=a[i++];}
while(j<=r){ans[a[j].tag]+=query(1,1,size,1,a[j].c);tmp[tot++]=a[j++];}
for(int k=l;k<=m;k++)add(1,1,size,a[k].c,-a[k].cnt);
for(int k=l;k<=r;k++)a[k]=tmp[k];
// testtree(l,r);
}
void test1(int l,int r)
{
printf("test\n");
for(int i=l;i<=r;i++){printf("%d\t%d\t%d\t%d\t%d\n",a[i].cnt,a[i].a,a[i].b,a[i].c,a[i].tag);}
printf("test1end\n\n");
}
void test2(int l,int r)
{
printf("test2\n");
for(int i=l;i<=r;i++){printf("%d\n",ans[i]);}
printf("test2end\n\n");
}
void test3(int l,int r)
{
for(int i=l;i<=r;i++){printf("%d\t%d\n",a[i].tag,ans[a[i].tag]);}
}
void test4(int l,int r)
{
printf("test4\n");
for(int i=l;i<=r;i++){printf("%d\t%d\t%d\t%d\t%d\t%d\n",a[i].cnt,a[i].a,a[i].b,a[i].c,a[i].tag,ans[a[i].tag]);}
printf("test4end\n\n");
}
int f[N];
bool eq(int i,int j)
{
return (tmp[i].a==a[j].a)&(tmp[i].b==a[j].b)&(tmp[i].c==a[j].c);
}
int main()
{
freopen("P3810_2.in","r",stdin);
freopen("P3810_2.txt","w",stdout);
memset(f,0,sizeof f);
int n=read();size=read();for(int i=1;i<=n;i++)a[i].a=read(),a[i].b=read(),a[i].c=read();
sort_a(1,n);
int len=0;
for(int i=1;i<=n;i++)
{
if(eq(len,i))tmp[len].cnt++;
else tmp[++len]=a[i],tmp[len].tag=len;
}
for(int i=1;i<=len;i++)a[i]=tmp[i],ans[a[i].tag]+=a[i].cnt-1;
// test1(1,len);
solve(1,len);
// test1(1,len);
// test2(1,len);
// test3(1,len);
// test4(1,len);
// fclose(stdin);
for(int i=1;i<=len;i++)f[ans[a[i].tag]]+=a[i].cnt;
for(int i=0;i<n;i++)printf("%d\n",f[i]);
fclose(stdout);
return 0;
}