【BZOJ 3262三维偏序】陌上花开

【BZOJ 3262三维偏序】陌上花开

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

Sample Output

3
1
3
0
1
0
1
0
0
1

Hint

数据范围:
1 <= N <= 100,000, 1 <= K <= 200,000

Source

CDQ分治,树套树

思路{

   CDQ分治维护三维偏序,第一维sort即可,第二维分治即可,第三维套树状数组求解;

   !:对于细节处理要注意!在分治时原先的树状数组记录的由于y的情况不同会有误!

   所以要多一个数组记录。

}

 1 #include<algorithm>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<cstdio>
 5 #include<vector>
 6 #include<queue>
 7 #include<ctime>
 8 #include<cmath>
 9 #include<map>
10 #include<set>
11 #define MAXX 1000010
12 #define lowbit(k) k&-k
13 using namespace std;
14 struct f{
15   int x,y,z,num,ans;
16 }e[MAXX*2];
17 int fa[MAXX*2],tree[MAXX*2],now,n,k,anss[MAXX*2];
18 //                                   shuzhuangshuzu
19 int sum(int p){
20   int num=0;
21   for(int k=p;k;k-=lowbit(k))
22     if(fa[k]==now)num+=tree[k];
23   return num;
24 }
25 void add(int p,int num){
26   for(int k=p;k<MAXX;k+=lowbit(k)){
27     if(fa[k]!=now)tree[k]=0;//yi jing ji suan guo
28     fa[k]=now;tree[k]+=num;
29   }
30 }
31 //                                   sort!!!!!!
32 bool Comp(const f & a,const f & b){
33   if(a.y==b.y)return a.z<a.z;
34   return a.y<b.y;
35 }
36 bool comp(const f & a,const f & b){
37   if(a.x==b.x){
38     if(a.y==b.y)return a.z<b.z;
39     return a.y<b.y;
40   }
41   return a.x<b.x;
42 }
43 //                                     CDQ   fenzhi!!
44 void CDQ(int l,int r){
45   if(l>=r)return;
46   int mid=(l+r)>>1;
47   CDQ(l,mid),CDQ(mid+1,r);
48   sort(e+l,e+mid+1,Comp),sort(e+mid+1,e+r+1,Comp);now++;int i,j;
49   for(j=mid+1,i=l;j<=r;++j){
50     for(;e[i].y<=e[j].y&&i<=mid;++i)add(e[i].z,e[i].num);
51     e[j].ans+=sum(e[j].z);
52    }
53 }
54 int main(){
55   scanf("%d%d",&n,&k);int nn=1;
56   for(int i=1;i<=n;++i)scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].z),e[i].num++;
57   sort(e+1,e+n+1,comp);
58   for(int i=2;i<=n;++i)
59     if(e[i].x!=e[nn].x||e[i].y!=e[nn].y||e[i].z!=e[nn].z)e[++nn]=e[i];
60     else e[nn].num++;
61   CDQ(1,nn);
62   for(int i=1;i<=nn;++i)anss[e[i].ans+e[i].num-1]+=e[i].num;
63   for(int i=0;i<n;++i)printf("%d\n",anss[i]);
64   return 0;
65 }

 

 

 si

posted @ 2017-03-31 08:33  QYP_2002  阅读(145)  评论(0编辑  收藏  举报