P3810 模板三维偏序(陌上花开)
Posted zhangbuang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P3810 模板三维偏序(陌上花开)相关的知识,希望对你有一定的参考价值。
题目描述
有 nn 个元素,第 ii 个元素有 a_iai?、b_ibi?、c_ici? 三个属性,设 f(i)f(i) 表示满足 a_j leq a_iaj?≤ai? 且 b_j leq b_ibj?≤bi? 且 c_j leq c_icj?≤ci?的 jj 的数量。
对于 d in [0, n)d∈[0,n),求 f(i) = df(i)=d 的数量
输入输出格式
输入格式:
第一行两个整数 nn、kk,分别表示元素数量和最大属性值。
之后 nn 行,每行三个整数 a_iai?、b_ibi?、c_ici?,分别表示三个属性值。
输出格式:
输出 nn 行,第 d + 1d+1 行表示 f(i) = df(i)=d 的 ii 的数量。
输入输出样例
输入样例#1: 复制
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
输出样例#1: 复制
3
1
3
0
1
0
1
0
0
1
说明
1 leq n leq 100000, 1 leq k leq 2000001≤n≤100000,1≤k≤200000
就是一维排序,一维cdq,一维数据结构,
然后就是要把萨格属性完全相同的要去掉,并在这个属性的个数上+1. 其他的就没什么了
其实一开始看到cdq是一脸懵逼的,怎么看也看不懂,但是理解了以后就会发现这玩意也挺简单的。
1 #include <cstdio>
2 #include <cstring>
3 #include <algorithm>
4
5 struct point{
6 int a,b,c,id;
7 point(){
8 a=b=c=id=0;
9 }
10 }num[100001],tem[100001];
11 bool cmp(point lhs,point rhs){
12 if(lhs.a!=rhs.a)return lhs.a<rhs.a;
13 if(lhs.b!=rhs.b)return lhs.b<rhs.b;
14 return lhs.c<rhs.c;
15 }
16 int c[200001],ans[100001],fin[100001],size[100001];
17 int n,k;
18 void update(int ind,int num){for(;ind<=k;ind+=ind&-ind)c[ind]+=num;}
19 long long query(int ind){
20 long long tot=0;
21 for(;ind;ind-=ind&-ind)tot+=c[ind];
22 return tot;
23 }
24 void cdq(int l,int r){
25 if(l==r)return;
26 int mid=(l+r)/2;
27 cdq(l,mid);cdq(mid+1,r);
28 int i=l,j=mid+1,ind=l;
29 while(i<=mid&&j<=r){
30 if(num[i].b<=num[j].b)update(num[i].c,size[num[i].id]),tem[ind++]=num[i++];
31 else ans[num[j].id]+=query(num[j].c),tem[ind++]=num[j++];
32 }
33 while(j<=r)ans[num[j].id]+=query(num[j].c),tem[ind++]=num[j++];
34 for(int e=l;e<i;e++)update(num[e].c,-size[num[e].id]);
35 while(i<=mid)tem[ind++]=num[i++];
36 for(int i=l;i<=r;i++)num[i]=tem[i];
37 }
38 int main(){
39 scanf("%d%d",&n,&k);
40 for(int i=1;i<=n;i++)scanf("%d%d%d",&num[i].a,&num[i].b,&num[i].c);
41 std::sort(num+1,num+n+1,cmp);
42 int ind=0;
43 for(int i=1;i<=n;i++){
44 if(num[i].a!=num[i-1].a||num[i].b!=num[i-1].b||num[i].c!=num[i-1].c)tem[++ind]=num[i];
45 size[ind]++;
46 }
47 for(int i=1;i<=ind;i++)num[i]=tem[i],num[i].id=i;
48 cdq(1,ind);
49 for(int i=1;i<=ind;i++)fin[ans[num[i].id]+size[num[i].id]-1]+=size[num[i].id];
50 for(int i=0;i<n;i++)printf("%d
",fin[i]);
51 }
以上是关于P3810 模板三维偏序(陌上花开)的主要内容,如果未能解决你的问题,请参考以下文章