1 4 10 4 7 10 6 6 8 2 5 7 3 10
1 1 0 0
很显然让你找(x,y,z)都大于别的(x,y,z),当然厉害的人可以用树套树水一下,但正解写的是CDQ分治,以x为第一关键字排序,以y为第二关键字来找,以z为第三关键字建一个树状数组找就好了,当然等于的情况可以实现前做一下。
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn=100000+100; const int N=100010; struct node { int id; int x,y,z; }a[maxn],tmp[maxn]; int dp[maxn],n; struct Bit { int c[maxn]; void init() { memset(c,0,sizeof(c)); } int lowbit(int x) { return x&-x; } void update(int x) { while(x<=N) { c[x]++; x+=lowbit(x); } } void modify(int x) { while(x<=N) { c[x]=0; x+=lowbit(x); } } int query(int x) { int ans=0; while(x>0) { ans+=c[x]; x-=lowbit(x); } return ans; } }bit; bool cmp(node a,node b) { if(a.x!=b.x) return a.x<b.x; if(a.y!=b.y) return a.y<b.y; return a.z<b.z; } bool cmp1(node a,node b) { if(a.y!=b.y) return a.y<b.y; return a.z<b.z; } void solve(int l,int r) { int i; if(l==r) return; int m=(l+r)>>1; solve(l,m); for(i=l;i<=r;i++) tmp[i]=a[i]; sort(tmp+l,tmp+m+1,cmp1); sort(tmp+m+1,tmp+r+1,cmp1); int p1=l; for(i=m+1;i<=r;i++) { while(p1<=m&&tmp[p1].y<=tmp[i].y) { bit.update(tmp[p1].z); p1++; } dp[tmp[i].id]+=bit.query(tmp[i].z); } for(i=l;i<=m;i++) bit.modify(tmp[i].z); solve(m+1,r); } int main() { int T,i; scanf("%d",&T); while(T--) { scanf("%d",&n); for(i=1;i<=n;i++) { scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z); a[i].id=i; } sort(a+1,a+1+n,cmp); memset(dp,0,sizeof(dp)); bit.init(); solve(1,n); for(i=n-1;i>=1;i--) { if(a[i].x==a[i+1].x&&a[i].y==a[i+1].y&&a[i].z==a[i+1].z) dp[a[i].id]=dp[a[i+1].id]; } for(i=1;i<=n;i++) printf("%d\n",dp[i]); } return 0; }