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(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.
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)
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;
}