HDU 5618 Jam's problem again(CDQ分治+树状数组(三维模板题))

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

扫描二维码关注公众号,回复: 1005384 查看本文章
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\n",p[i].ans);
	}
    
    return 0;
}

猜你喜欢

转载自blog.csdn.net/vocaloid01/article/details/80424265