众所周知三维偏序可以树套树或者cdq
然后我就写了二维离散化+二维树状数组
然后被cdq艹飞了(ToT)
#include<cstdio> #include<algorithm> #define N 100005 #define J i+(i&-i) #define F lower_bound #define G upper_bound using namespace std; struct io_t{ operator int(){ int x; scanf("%d",&x); return x; } }it; struct vec{ int i,j,k; }s[N]; bool operator<(vec a,vec b){ return a.i^b.i? a.i<b.i:a.j^b.j? a.j<b.j:a.k<b.k; } bool operator!=(vec i,vec j){ return i<j||j<i; } int e[N*40],*q=e; struct node{ int sum(int i){ int j=0; for(i=G(u,u+s,i)-u; i;i^=i&-i) j+=v[i-1]; return j; } void add(int i){ for(i=G(u,u+s,i)-u; i<=s;i+=i&-i) ++v[i-1]; } int s,*u,*v; void alloc(){ u=q,q+=s; v=q,q+=s,s=0; } void ins(int i){ u[s++]=i; } void ins(node& a){ for(int i=0;i!=a.s;++i) u[s++]=a.u[i]; } void init(){ sort(u,u+s); s=unique(u,u+s)-u; } }t[N]; int n,m,l[N],v[N]; int main(){ n=it,~it; for(int i=0;i!=n;++i){ s[i].i=it; s[i].j=l[i]=it; s[i].k=it; } sort(l,l+n); m=unique(l,l+n)-l; sort(s,s+n); for(int i=0;i!=n;++i) ++t[s[i].j=F(l,l+m, s[i].j)-l+1].s; for(int i=1;i<=m;++i){ if(J<=m) t[J].s+=t[i].s; t[i].alloc(); } for(int i=0;i!=n;++i) t[s[i].j].ins(s[i].k); for(int i=1;i<=m;++i){ t[i].init(); if(J<=m) t[J].ins(t[i]); } for(int i=0,j=-1;i!=n;++i){ if(s[i+1]!=s[i]){ int* u=v; for(int k=s[i].j; k;k^=k&-k) u+=t[k].sum(s[i].k); *u+=i-j,j=i; } for(int k=s[i].j; k<=m;k+=k&-k) t[k].add(s[i].k); } for(int i=0;i!=n;++i) printf("%d\n",v[i]); }
时间: 2024-10-12 16:20:42