Jam's problem again
Time Limit: 5000/2500 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1417 Accepted Submission(s): 504
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.
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
Source
BestCoder Round #70
Recommend
hujie | We have carefully selected several similar problems for you: 6216 6215 6214 6213 6212
题目大意:求对于每个点,满足以下条件的点数
(xi,yi,zi)
and
(xj,yj,zj) xi≥xj yi≥yj zi≥zj
题目思路:
这个的话,我们还是像二维偏序一样。
先把第一维排序。
然后我们就可以忽略第一维的影响了。
对于任意i<=j,满足x[i]<=x[j]。
然后我们还是采用归并的思路。
现在有两个有序的区间 [l,mid] 与 [mid+1,r]
那么我们开始计算左区间对右区间的贡献。
归并的时候我们有双指针。
假设a是左区间指针的当前位置 b是右区间当前指针的当前位置。
需要对z的权值建立一颗树状数组
双指针开始扫。
① a.y把 add(a.z,1)
a弹出,因为a对b及b以后的都有可能有贡献。
② a.y>b.y 的话 b这个点的贡献 += Getsum(b.z)
b弹出 ,因为a及a后面的都不可能对b有贡献了。
细节:注意处理一下两点重合的情况。
代码实现:
#include
using namespace std;
const int maxn=1e5+10;
#define lowerbit(x) x&-x
struct Point
{
int x,y,z,id,cnt;
bool operator == (const Point& t)
{
if(x==t.x&&y==t.y&&z==t.z) return true;
return false;
}
}query[maxn],tmp[maxn],initarr[maxn];
int ans[maxn],sum[maxn],cnt,same,maxz;
bool cmp(const Point& a,const Point& b)//横坐标为第一维,排序。
{
if(a.xb.x) return false;
if(a.yb.y) return false;
if(a.zb.z) return false;
return a.id0)
{
res+=sum[pos];
pos-=lowerbit(pos);
}
return res;
}
void Clrtree(int pos)//清空树状数组
{
while(pos=r) return;
int mid=(l+r)>>1;
CDQ(l,mid);
CDQ(mid+1,r);
int p=l,q=mid+1,o=0;
while(p<=mid&&q<=r)
{
if(query[p].y<=query[q].y)
{
Update(query[p].z,query[p].cnt);
tmp[o++]=query[p++];
}
else
{
ans[query[q].id]+=Getsum(query[q].z);
tmp[o++]=query[q++];
}
}
while(p<=mid) tmp[o++]=query[p++];
while(q<=r)
{
ans[query[q].id]+=Getsum(query[q].z);
tmp[o++]=query[q++];
}
for(int i=l;i<=mid;i++) Clrtree(query[i].z);
for(int i=0;i=0;i--)
if(initarr[i]==initarr[i+1])
ans[initarr[i].id]=ans[initarr[i+1].id];
}
int main()
{
int T,n;
scanf("%d",&T);
while(T--)
{
memset(ans,0,sizeof(ans));
memset(sum,0,sizeof(sum));
scanf("%d",&n);
maxz=0;
for(int i=0;i