Jam like to solve the problem which on the 3D-axis,given N(1<=N<=100000) points (x,y,z)(1<=x,y,z<=100000)
If two point such as (xi,yi,zi) and (xj,yj,zj) xi>=xj,yi>=yj,zi>=zj,the bigger one level add 1.
Ask for the each level of the point.
Input
The first line is T(1<=T<=15) means T Case
For each case
The first line is N means the number of Point and next there are N line, each line has (x,y,z)
Output
Output with N line,each line has one number means the lever of point
Sample Input
1 4 10 4 7 10 6 6 8 2 5 7 3 10
Sample Output
1 1 0 0
代码:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn = 100005;
int n;
struct node
{
int x,y,z,ans,number;//ans表示比自己小的点得个数,number是输入时顺序编号。
}p[maxn];
bool cmpx(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 cmpy(node a,node b)
{
if(a.y!=b.y)return a.y<b.y;
return a.z<b.z;
}
bool cmpn(node a,node b)
{
return a.number < b.number;
}
struct BIT //树状数组
{
#define lowbit(x) (x&(-x))
int b[maxn];
void init()
{
memset(b,0,sizeof(b));
}
void update(int x,int v)
{
while(x<=maxn)
{
b[x]+=v;
x+=lowbit(x);
}
}
int query(int x)
{
int ans=0;
while(x)
{
ans+=b[x];
x-=lowbit(x);
}
return ans;
}
void clear(int x)
{
while(x<=maxn)
{
b[x]=0;
x+=lowbit(x);
}
}
}bit;
void CDQ(int l,int r)
{
if(l==r)
{
return ;
}
int mid = l + (r-l)/2;
CDQ(l,mid);
CDQ(mid+1,r);
sort(p+l,p+mid+1,cmpy);
sort(p+mid+1,p+r+1,cmpy);
int j=l;
for(int i=mid+1;i<=r;i++)
{
for(;j<=mid&&p[j].y<=p[i].y;j++)
bit.update(p[j].z,1);
p[i].ans += bit.query(p[i].z);
}
for(int i=l;i<j;i++)bit.update(p[i].z,-1);//把加入的值再去掉。
}
int main()
{
int T;
scanf("%d",&T);
while(T--){
bit.init();
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d%d%d",&p[i].x,&p[i].y,&p[i].z),p[i].ans=0,p[i].number = i;
sort(p+1,p+n+1,cmpx);
CDQ(1,n);
for(int i = 1;i <= n;)//处理重复点,因为如果有重复点那么其中肯定有一些重复点(x1,y1,z1)==(x2,y2,z2)的情况没算上。
{
int j = i + 1;
int tmp = p[i].ans;
for(;j <= n && p[i].x == p[j].x && p[i].y == p[j].y && p[i].z == p[j].z ;++ j)tmp = max(tmp,p[j].ans);
for(int k = i;k < j;k ++)p[k].ans = tmp;
i = j;
}
sort(p+1,p+1+n,cmpn);//恢复初始顺序
for(int i=1;i<=n;i++)printf("%d
",p[i].ans);
}
return 0;
}