【bzoj3262】陌上花开
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
1 <= N <= 100,000, 1 <= K <= 200,000
CDQ分治的裸题,三维偏序。
先对于一维排序,满足ai递增,然后在分成的两端区间中,左区间以bi排序,右区间以bi排序,处理左
区间对右区间的影响,因为左区间的ai一定<=右区间ai,然后类似归并操作,如果左bi<=右bi则将
ci放入树状数组中即可,然后bi查询一下,有多少个。
1 #include<cstring> 2 #include<cmath> 3 #include<cstdio> 4 #include<iostream> 5 #include<algorithm> 6 7 #define ll long long 8 #define NN 2000007 9 using namespace std; 10 inline int read() 11 { 12 int x=0,f=1;char ch=getchar(); 13 while(ch<'0'||ch>'9'){if (ch=='-')f=-1;ch=getchar();} 14 while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();} 15 return f*x; 16 } 17 18 int n,m,tr[NN],ans[NN]; 19 struct Node 20 { 21 int a,b,c,s,ans; 22 }a[NN],p[NN]; 23 24 inline int lowbit(int x) 25 { 26 return x&(-x); 27 } 28 inline void updata(int x,int num) 29 { 30 for (int i=x;i<=m;i+=lowbit(i)) 31 tr[i]+=num; 32 } 33 inline int query(int x) 34 { 35 int res=0; 36 for (int i=x;i>=1;i-=lowbit(i)) 37 res+=tr[i]; 38 return res; 39 } 40 inline bool cmp1(Node x,Node y) 41 { 42 if (x.a==y.a&&x.b==y.b) return x.c<y.c; 43 if (x.a==y.a) return x.b<y.b; 44 return x.a<y.a; 45 } 46 inline bool cmp2(Node x,Node y) 47 { 48 if (x.b==y.b) return x.c<y.c; 49 return x.b<y.b; 50 } 51 void cdq(int l,int r) 52 { 53 54 if (l==r) return; 55 int mid=(l+r)>>1; 56 cdq(l,mid),cdq(mid+1,r); 57 sort(p+l,p+mid+1,cmp2),sort(p+mid+1,p+r+1,cmp2); 58 int i=l,j=mid+1; 59 while(j<=r) 60 { 61 while(i<=mid&&p[i].b<=p[j].b) 62 { 63 updata(p[i].c,p[i].s); 64 i++; 65 } 66 p[j].ans+=query(p[j].c); 67 j++; 68 } 69 for (int j=l;j<i;j++)//只能到i为止 70 updata(p[j].c,-p[j].s); 71 } 72 int main() 73 { 74 int N=read();m=read(); 75 for (int i=1;i<=N;i++) 76 a[i].a=read(),a[i].b=read(),a[i].c=read(); 77 sort(a+1,a+N+1,cmp1); 78 int cnt=0; 79 for (int i=1;i<=N;i++) 80 { 81 cnt++; 82 if (a[i].a!=a[i+1].a||a[i].b!=a[i+1].b||a[i].c!=a[i+1].c) 83 { 84 p[++n]=a[i]; 85 p[n].s=cnt; 86 cnt=0; 87 } 88 } 89 cdq(1,n); 90 for (int i=1;i<=n;i++) 91 ans[p[i].ans+p[i].s-1]+=p[i].s; 92 for (int i=0;i<N;i++) 93 printf("%d ",ans[i]); 94 }