• 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

    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;
    }

  • 相关阅读:
    xavier NX编译caffe错误记录(二)
    ubuntu16安装微信
    linux中安装onenote(P3X OneNote)
    ubuntu16中,google浏览器安装OneNote Web Clipper插件
    酒店门锁接口说明
    在xaf 14 中实现 Tonyyang原文中的action权限
    MRP生产计划模式在多品种小批量生产过程中遭遇挑战
    C#代码
    简陋的会计凭证金额输入控件(加强) [转]
    简陋的会计凭证金额输入控件(再加强) [转]
  • 原文地址:https://www.cnblogs.com/vocaloid01/p/9514110.html
Copyright © 2020-2023  润新知