hdu5618Jam's problem again (CDQ分治)
2017-10-12 08:59
561 查看
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
1
1
0
0
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<b.y的话。把 add(a.z,1)
a弹出,因为a对b及b以后的都有可能有贡献。
②
a.y>b.y 的话 b这个点的贡献 += Getsum(b.z)
b弹出
,因为a及a后面的都不可能对b有贡献了。
细节:注意处理一下两点重合的情况。
代码实现:
#include<bits/stdc++.h> 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.x<b.x) return true; if(a.x>b.x) return false; if(a.y<b.y) return true; if(a.y>b.y) return false; if(a.z<b.z) return true; if(a.z>b.z) return false; return a.id<b.id; } void Update(int pos,int val) { while(pos<maxz+1) { sum[pos]+=val; pos+=lowerbit(pos); } } int Getsum(int pos) { int res=0; while(pos>0) { res+=sum[pos]; pos-=lowerbit(pos); } return res; } void Clrtree(int pos)//清空树状数组 { while(pos<maxz+1) { sum[pos]=0; pos+=lowerbit(pos); } } void CDQ(int l,int r) { if(l>=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<o;i++) query[i+l]=tmp[i]; } void Setans(int n)//处理重复的 { for(int i=n-2;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<n;i++) { scanf("%d%d%d",&initarr[i].x,&initarr[i].y,&initarr[i].z); initarr[i].id=i;//记录初始位置,便于输出答案。 initarr[i].cnt=1; maxz=max(maxz,initarr[i].z); } sort(initarr,initarr+n,cmp); for(int i=0;i<n;i++) query[i]=initarr[i]; CDQ(0,n-1);//左闭右闭区间 Setans(n);//去重的东西重新覆盖 for(int i=0;i<n;i++) printf("%d\n",ans[i]); } }
相关文章推荐
- noi2007货币兑换 cdq分治优化dp方程
- 时间分治(cdq分治)
- BZOJ-1492-货币兑换cash-NOI2007-CDQ分治
- BZOJ1176【CDQ分治】【树状数组】
- BZOJ 2716: [Violet 3]天使玩偶( CDQ分治 + 树状数组 )
- BZOJ2683 简单题(CDQ分治)
- [动态最小生成树 CDQ分治 Kruscal] BZOJ 2001 [Hnoi2010]City 城市建设
- [DP 斜率优化 CDQ分治||动态维护凸包] BZOJ 1492 [NOI2007]货币兑换Cash
- 整体二分&CDQ分治:[BZOJ2527][POI2011] meteors [BZOJ3295][CQOI2011] 动态逆序对
- 初学CDQ分治-NEU1702
- [CDQ分治 并查集] BZOJ 1453 [Wc]Dface双面棋盘
- 学习笔记——cdq分治
- 【BZOJ 3262】陌上开花 CDQ分治
- [BZOJ1176][[Balkan2007]Mokia][CDQ分治]
- 【BZOJ3963】【ACM-WF2011】MachineWorks(CDQ分治+斜率优化)
- 整体二分&cdq分治的小总结
- BZOJ 2225 [Spoj 2371]Another Longest Increasing(CDQ分治)
- USACO月赛2017.02 铂金组T3--FRIENDCROSS【CDQ分治】
- bzoj 3262 陌上花开 - CDQ分治 - 树状数组
- BZOJ4237:稻草人 (CDQ分治+二分+单调栈)