BZOJ - 3262 陌上花开
3262: 陌上花开
Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 5433 Solved: 2623
[Submit][Status][Discuss]
Description
有n朵花,每朵花有三个属性:花形(s)、颜色(c)、气味(m),用三个整数表示。
现在要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量。
定义一朵花A比另一朵花B要美丽,当且仅Sa>=Sb,Ca>=Cb,Ma>=Mb。
显然,两朵花可能有同样的属性。需要统计出评出每个等级的花的数量。
Input
第一行为N,K (1 <= N <= 100,000, 1 <= K <= 200,000 ), 分别表示花的数量和最大属性值。
以下N行,每行三个整数si, ci, mi (1 <= si, ci, mi <= K),表示第i朵花的属性
Output
包含N行,分别表示评级为0...N-1的每级花的数量。
Sample Input
10 3
3 3 3
2 3 3
2 3 1
3 1 1
3 1 2
1 3 1
1 1 2
1 2 2
1 3 2
1 2 1
3 3 3
2 3 3
2 3 1
3 1 1
3 1 2
1 3 1
1 1 2
1 2 2
1 3 2
1 2 1
Sample Output
3
1
3
0
1
0
1
0
0
1
1
3
0
1
0
1
0
0
1
HINT
Source
三维偏序 先码下cdq
#include<bits/stdc++.h> #define ll long long #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define inf 0x3f3f3f3f #define eps 1e-6 using namespace std; const int maxn = 100005; struct node{ int x,y,z,cnt,ans; }p[maxn]; int tree[maxn*2],k,ans[maxn]; int lowbit(int x){ return x&(-x); } bool cmpx(const node u,const node v){ if(u.x==v.x&&u.y==v.y) return u.z<v.z; if(u.x==v.x) return u.y<v.y; return u.x<v.x; } bool cmpy(const node u,const node v){ if(u.y==v.y&&u.z==v.z) return u.x<v.x; if(u.y==v.y) return u.z<v.z; return u.y<v.y; } void add(int x,int val){ while(x<=k){ tree[x]+=val; x+=lowbit(x); } } int query(int x){ int ans=0; while(x){ ans+=tree[x]; x-=lowbit(x); } return ans; } void cdq(int l,int r){ if(l==r){ p[l].ans+=p[l].cnt-1; return ; } int m=(l+r)>>1; cdq(l,m); cdq(m+1,r); sort(p+l,p+1+m,cmpy); sort(p+1+m,p+1+r,cmpy); int j=l; for(int i=m+1;i<=r;i++){ while(j<=m&&p[j].y<=p[i].y){ add(p[j].z,p[j].cnt); j++; } p[i].ans+=query(p[i].z); } for(int i=l;i<j;i++) add(p[i].z,-p[i].cnt); } int main(){ int n,tot=0; scanf("%d%d",&n,&k); for(int i=1;i<=n;i++){ scanf("%d %d %d",&p[i].x,&p[i].y,&p[i].z); p[i].ans=1; } sort(p+1,p+1+n,cmpx); for(int i=1;i<=n;i++){ if(i!=1&&p[i].x==p[i-1].x&&p[i].y==p[i-1].y&&p[i].z==p[i-1].z){ p[tot].cnt++; }else { p[++tot]=p[i]; p[tot].cnt=1; } } cdq(1,tot); for(int i=1;i<=tot;i++){ ans[p[i].ans]+=p[i].cnt; } for(int i=1;i<=n;i++){ cout<<ans[i]<<"\n"; } return 0; }