hdu5618 Jam's problem again(cdq分治)(BestCoder Round #70)

Jam's problem again

 Time Limit: 5000/2500 MS (Java/Others)
 
 Memory Limit: 65536/65536 K (Java/Others)
问题描述
Jam喜欢坐标轴上的题,现在给出你一个三维的坐标轴,给出NN个点,坐标分别为(x,y,z)(x,y,z)
如果有两个点(x_i, y_i, z_i)(xi,yi,zi)(x_j, y_j, z_j)(xj,yj,zj)x_i \geq xj \ y_i \geq y_j \ z_i \geq z_jxixj yiyj zizj 时 这个点的等级就加一,每个等级一开始为00
当然1 \leq x,y,z \leq 100000 \ 1 \leq N \leq 1000001x,y,z100000 1N100000
现在求每个点的等级
输入描述
第一行T(1 \leq T \leq 15)T(1T15),表示TT组数据。
接下来TT组数据:
第一行为NN,表示点的数目
接下来NN行,每一行三个整数x,y,zx,y,z表示点的坐标
输出描述
输出N行,每行表示每个点的等级
输入样例
1
4
10 4 7
10 6 6
8 2 5
7 3 10
输出样例
1
1
0
0
Hint
第一个比第三个大,所以等级为1
第二个比第三个大,所以等级为1
分析:分治加树状数组
首先,我们可以对x按从小到大进行排序,分治的过程便是简单的cdq分治
#include<bits/stdc++.h>
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 u,node v){
    if(u.x!=v.x)
        return u.x<v.x;
    if(u.y!=v.y)
        return u.y<v.y;
    return u.z<v.z;
}

bool cmp1(node u,node v){
    if(u.y!=v.y)
        return u.y<v.y;
    return u.z<v.z;
}

void solve(int l,int r){
    if(l==r)
        return ;
    int m=(l+r)>>1;
    solve(l,m);
    for(int 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 pl=l;
    for(int i=m+1;i<=r;i++){
        while(pl<=m&&tmp[pl].y<=tmp[i].y){
            bit.update(tmp[pl].z);
            pl++;
        }
        dp[tmp[i].id]+=bit.query(tmp[i].z);
    }
    for(int i=l;i<=m;i++)
        bit.modify(tmp[i].z);
    solve(m+1,r);
}

int main(){
    int _;
    scanf("%d",&_);
    while(_--){
        scanf("%d",&n);
        for(int 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+n+1,cmp);
        memset(dp,0,sizeof(dp));
        bit.init();
        solve(1,n);
        for(int 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(int i=1;i<=n;i++)
            printf("%d\n",dp[i]);
    }
    return 0;
}

你可能感兴趣的:(BestCoder)