#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
inline ll read() {
ll f=1,x=0;char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)) {x=x*10+ch-48;ch=getchar();}
return x*f;
}
const ll N=200005;
struct V {
ll a,b,c,app,bh;
}v[N];
bool precmp(V x,V y) {
if(x.a==y.a) {
if(x.b==y.b) return x.c>y.c;
return x.b>y.b;
}
return x.a>y.a;
}
bool stb(V x,V y) {
if(x.b==y.b) return x.c>y.c;
return x.b>y.b;
}
ll n,k,ans[N],fn[N];
bool equal(int x,int y) {
return ((v[x].a==v[y].a)&(v[x].b==v[y].b)&(v[x].c==v[y].c));
}
struct SGtree {
ll nd[4*N],sum;
void pushup(int t) {
nd[t]=nd[2*t]+nd[2*t+1];
}
void Clear(int t,int l,int r) {
if(l==r) {
nd[t]=0;
return ;
}
int mid=(l+r)/2;
Clear(2*t,l,mid);
Clear(2*t+1,mid+1,r);
pushup(t);
}
void clear() {
Clear(1,1,k);
}
void Query(int t,int l,int r,int ll,int rr) {
if(ll<=l&&r<=rr) {
sum+=nd[t];
return ;
}
int mid=(l+r)/2;
if(ll<=mid) Query(2*t,l,mid,ll,rr);
if(rr>=mid+1) Query(2*t+1,mid+1,r,ll,rr);
}
ll query(int l,int r) {
sum=0;
Query(1,1,k,l,r);
return sum;
}
void Update(int t,int l,int r,int p,int val) {
if(l==r) {
nd[t]+=val;
return ;
}
int mid=(l+r)/2;
if(p<=mid) Update(2*t,l,mid,p,val);
if(p>=mid+1) Update(2*t+1,mid+1,r,p,val);
pushup(t);
}
void update(int p,int val) {
Update(1,1,k,p,val);
}
}sgt;
void solve(int l,int r) {
if(l==r) return ;
int mid=(l+r)/2;
solve(l,mid);
solve(mid+1,r);
// sgt.clear();
sort(v+l,v+mid+1,stb);
sort(v+mid+1,v+r+1,stb);
// cout<<l<<' '<<r<<'\n';
// for(int i=1;i<=n;i++) cout<<v[i].a<<' ';
// cout<<'\n';
// sgt.clear();
for(int i=mid+1;i<=r;i++) sgt.update(v[i].c,v[i].app);
int lp,rp;
for(lp=l,rp=mid;lp<=mid;lp++) {
while(rp<r&&v[rp+1].b>v[lp].b) {
rp++;
sgt.update(v[rp].c,-v[rp].app);
}
// if(v[lp].bh==3) cout<<"AD"<<l<<' '<<r<<' '<<lp<<' '<<sgt.query(1,v[lp].c)<<'\n';
ans[v[lp].bh]+=sgt.query(1,v[lp].c);
}
while(rp<r) {
rp++;
sgt.update(v[rp].c,-v[rp].app);
}
sort(v+l,v+r+1,precmp); //--------------
}
int main() {
// freopen("input.txt","r",stdin);
// freopen("output.txt","w",stdout);
n=read(),k=read();
for(int i=1;i<=n;i++) {
v[i].a=read(),v[i].b=read(),v[i].c=read();
v[i].app=1;
}
sort(v+1,v+n+1,precmp);
ll nw=n;
for(int i=1;i<=n;i++) {
// cout<<i<<' '<<v[i].a<<' '<<v[i].b<<' '<<v[i].c<<'\n';
if(equal(i,i+1)) v[i].a=0,nw--,v[i+1].app+=v[i].app;
}
sort(v+1,v+n+1,precmp);
ll tmp=n;
n=nw;nw=tmp;
for(int i=1;i<=n;i++) v[i].bh=i;
solve(1,n);
for(int i=1;i<=n;i++) {
// cout<<v[i].a<<' '<<ans[i]<<' '<<v[i].app<<'\n';
// if(ans[i]+v[i].app-1==1) {
// cout<<i<<' '<<v[i].a<<' '<<v[i].b<<' '<<v[i].c<<'\n';
// }
fn[ans[i]+v[i].app-1]+=v[i].app;
}
for(int i=0;i<=nw-1;i++) cout<<fn[i]<<'\n';
return 0;
}
正常来说solve函数的倒数第二行的sort(v+l,v+r+1,precmp);不加就能通过,但我发现只有加上才能过。有没有大佬能指点一下,谢谢。