HDU5618-Jam's problem again(cdq分治)

63 篇文章 0 订阅
3 篇文章 0 订阅

Jam's problem again

                                                                    Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
                                                                                            Total Submission(s): 1349    Accepted Submission(s): 483


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
 

Recommend
hujie
 


题意: 三维坐标,对于每1个点,找出有多少个点,3个坐标都比该点小

解题思路:cdq分治+树状数组或cdq分治+cdq分治,cdq分治+cdq分治理解了较长时间


cdq分治+树状数组:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <map>
#include <cmath>
#include <set>
#include <stack>
#include <queue>
#include <vector>
#include <bitset>
#include <functional>

using namespace std;

#define LL long long
const int INF = 0x3f3f3f3f;

int n,ans[100005],x[100005];

struct node
{
    int x,y,z,id,sum;
}a[100005];

bool cmp1(node a,node b)
{
    return a.x == b.x ? (a.y == b.y ? a.z < b.z : a.y < b.y) : a.x < b.x;
}

bool cmp2(node a,node b)
{
    return a.y < b.y;
}

int lowbit(int k) {return k&-k;}
void update(int k,int val) {for(;k<=100000;k+=lowbit(k)) x[k]+=val;}
int getsum(int k) {int sum=0;for(;k;k-=lowbit(k)) sum+=x[k];return sum;}

void solve(int l,int r)
{
    if(l==r) return ;
    int mid=(l+r)>>1;
    solve(l,mid),solve(mid + 1,r);
    sort(a+l,a+mid+1,cmp2);
    sort(a+mid+1,a+r+1,cmp2);
    int j=l;
    for(int i=mid+1;i<=r;i++)
    {
        for(;j<=mid&&a[j].y<=a[i].y;j++) update(a[j].z,1);
        a[i].sum+=getsum(a[i].z);
    }
    for(j--;j>=l;j--) update(a[j].z,-1);
}

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        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,a[i].sum=0;
        memset(x,0,sizeof x);
        sort(a+1,a+1+n,cmp1);
        solve(1,n);
        for(int i=1;i<=n;)
        {
            int j=i+1;
            int tmp=a[i].sum;
            for(;j<=n&&a[i].x==a[j].x&&a[i].y==a[j].y&&a[i].z==a[j].z;j++) tmp=max(tmp,a[j].sum);
            for(int k=i;k<j;k++) ans[a[k].id]=tmp;
            i=j;
        }
        for(int i=1;i<=n;i++) printf("%d\n",ans[i]);
    }
    return 0;
}


cdq分治+cdq分治:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <map>
#include <cmath>
#include <set>
#include <stack>
#include <queue>
#include <vector>
#include <bitset>
#include <functional>

using namespace std;

#define LL long long
const int INF = 0x3f3f3f3f;

int n,ans[100005];

struct node
{
    int x,y,z,id,sum,flag;
}a[100005],b[100005],c[100005];

bool cmp(node a,node b)
{
    return a.x == b.x ? (a.y == b.y ? a.z < b.z : a.y < b.y) : a.x < b.x;
}

void solve2(int l,int r)
{
    if(l==r) return ;
    int mid=(l+r)>>1;
    solve2(l,mid),solve2(mid+1,r);
    for(int i=l,j=l,k=mid+1,sum=0;i<=r;i++)
    {
        if((b[j].z<=b[k].z||k>r)&&j<=mid) c[i]=b[j++],sum+=c[i].flag^1;
        else
        {
            c[i]=b[k++];
            if(c[i].flag) ans[c[i].id]+=sum;
        }
    }
    for(int i=l;i<=r;i++) b[i]=c[i];
}

void solve1(int l,int r)
{
    if(l==r) return ;
    int mid=(l+r)>>1;
    solve1(l,mid),solve1(mid+1,r);
    for(int i=l,j=l,k=mid+1;i<=r;i++)
    {
        if((a[j].y<=a[k].y||k>r)&&j<=mid) b[i]=a[j++],b[i].flag=0;
        else b[i]=a[k++],b[i].flag=1;
    }
    for(int i=l;i<=r;i++) a[i]=b[i];
    solve2(l,r);
}

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        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,a[i].sum=0;
        memset(ans,0,sizeof ans);
        sort(a+1,a+1+n,cmp);
        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) ans[a[i].id]=ans[a[i+1].id]+1;
        solve1(1,n);
        for(int i=1;i<=n;i++) printf("%d\n",ans[i]);
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值