Description
有 $ n $ 个元素,第 $ i $ 个元素有 $ a_i $ 、$ b_i $ 、$ c_i $ 三个属性,设 $ f(i) $ 表示满足 $ a_j leq a_i $ 且 $ b_j leq b_i $ 且 $ c_j leq c_i $ 的 $ j $ 的数量。
对于 $ d in [0, n) $ ,求 $ f(i) = d $ 的数量
Input
第一行两个整数 $ n $ 、$ k $ ,分别表示元素数量和最大属性值。
之后 $ n $ 行,每行三个整数 $ a_i $ 、$ b_i $ 、$ c_i $ ,分别表示三个属性值。
Output
输出 $ n $ 行,第 $ d + 1 $ 行表示 $ f(i) = d $ 的 $ i $ 的数量。
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 leq n leq 100000, 1 leq k leq 200000 $
题解
$CDQ$ 分治模板题。
三维:
第一维 $sort$ 排序
第二维 $CDQ$
第三维 $bittree$
我们将第一维排序后,我们用递归实现 $CDQ$ ,取 $mid$ ,算出 $mid$ 左边对 $mid$ 右边的贡献。
用 $bittree$ 来维护最后一维的大小关系。
1 #include<set> 2 #include<map> 3 #include<cmath> 4 #include<ctime> 5 #include<queue> 6 #include<stack> 7 #include<cstdio> 8 #include<string> 9 #include<vector> 10 #include<cstdlib> 11 #include<cstring> 12 #include<iostream> 13 #include<algorithm> 14 #define lowbit(x) ((x)&-(x)) 15 using namespace std; 16 const int N=100000; 17 const int K=200000; 18 19 struct point 20 { 21 int a,b,c,cnt,ans; 22 }g[N+5]; 23 int n,m,ans[N+5],c[K+5],num; 24 bool cmp2(point x,point y) {return x.b==y.b ? x.c<y.c:x.b<y.b;} 25 bool cmp1(point x,point y) {return x.a==y.a ? cmp2(x,y):x.a<y.a;} 26 void Add(int x,int y) {for (;x<=m;x+=lowbit(x)) c[x]+=y;} 27 int Count(int x) 28 { 29 int r=0; 30 for (;x;x-=lowbit(x)) r+=c[x]; 31 return r; 32 } 33 void CDQ(int l,int r) 34 { 35 if(l==r) return; 36 int mid=(l+r)>>1; 37 CDQ(l,mid); 38 CDQ(mid+1,r); 39 sort(g+l,g+mid+1,cmp2); 40 sort(g+mid+1,g+r+1,cmp2); 41 int t1=l,t2=mid+1; 42 while(t2<=r) 43 { 44 while(t1<=mid&&g[t1].b<=g[t2].b) 45 { 46 Add(g[t1].c,g[t1].cnt); 47 t1++; 48 } 49 g[t2].ans+=Count(g[t2].c); 50 t2++; 51 } 52 for (int i=l;i<=t1-1;i++) Add(g[i].c,-g[i].cnt); 53 } 54 int main() 55 { 56 scanf("%d%d",&n,&m); 57 for (int i=1;i<=n;i++) scanf("%d%d%d",&g[i].a,&g[i].b,&g[i].c),g[i].cnt=1; 58 sort(g+1,g+n+1,cmp1); 59 for (int i=1;i<=n;i++) 60 { 61 int k=i+1; 62 while(g[i].a==g[k].a&&g[i].b==g[k].b&&g[i].c==g[k].c) k++; 63 num++; 64 k--; 65 g[i].cnt+=k-i; 66 g[num]=g[i]; 67 i=k; 68 } 69 CDQ(1,num); 70 for (int i=1;i<=num;i++) ans[g[i].ans+g[i].cnt-1]+=g[i].cnt; 71 for (int i=0;i<n;i++) printf("%d ",ans[i]); 72 return 0; 73 }