hdoj 5618 Jam's problem again(cdq分治+树状数组)

Jam's problem again


Problem Description
Jam like to solve the problem which on the 3D-axis,given  N(1N100000) points  (x,y,z)(1x,y,z100000)

If two point such as  (xi,yi,zi) and  (xj,yj,zj) xixj yiyj zizj, the bigger one level add  1

Ask for the each level of the point.
 

Input
The first line is  T(1T15) 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
 

Source
BestCoder Round #70



很显然让你找(x,y,z)(x,y,z)都大于别的(x,y,z)(x,y,z),当然厉害的人可以用树套树水一下,但正解写的是CDQ分治,以xx为第一关键字排序,以yy为第二关键字来找,以zz为第三关键字建一个树状数组找就好了,当然等于的情况可以实现前做一下。

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

你可能感兴趣的:(hdoj 5618 Jam's problem again(cdq分治+树状数组))