Skip to content

Commit be22a8d

Browse files
committed
Update 2026-2-17-1.md
1 parent 87e97f5 commit be22a8d

1 file changed

Lines changed: 181 additions & 6 deletions

File tree

_posts/2026-2-17-1.md

Lines changed: 181 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
---
22
layout: post
3-
title: "题解:【模板】三维偏序 / 陌上花开"
4-
subtitle: "树套树三维偏序"
5-
date: 2026-2-16
3+
title: "高维偏序"
4+
subtitle: "树套树三维偏序/高维偏序"
5+
date: 2026-2-17
66
author: "TH911"
77
header-img: "img/2024/10/006.jpeg"
88
header-mask: 0.4
@@ -11,15 +11,190 @@ tags:
1111
- 题解
1212
- 树套树
1313
- 省选/NOI−
14+
- 未完
1415
words:
16+
- 题解:题解:【模板】三维偏序 / 陌上花开
1517
---
1618

17-
> [题目传送门](https://www.luogu.com.cn/problem/P3810)
19+
> [不知道从哪里下的 PDF](https://th911.dpdns.org/file/2026/02/FHR-分块bitset求高维偏序.pdf),感觉写的很好。
20+
21+
处理偏序问题时,需要考虑两个元素完全相同的情况,这时需要该元素 $a$ 的统计个数 $\textit{cnt}$,然后统计满足偏序条件元素个数 $x$,则 $a$ 的答案为 $x-1$,同时直接做 $\textit{cnt}$ 的贡献。
22+
23+
# 一维偏序
24+
25+
排序即可。
26+
27+
# 二维偏序
28+
29+
排序之后树状数组统计即可。
30+
31+
比如逆序对。
32+
33+
# 三维偏序
34+
35+
> [luogu P3810 【模板】三维偏序 / 陌上花开](https://www.luogu.com.cn/problem/P3810)
1836
>
19-
> 有 $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 \ne i $ 的 $j$ 的数量。
37+
> 有 $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 \ne i $ 的 $j$ 的数量。
2038
>
2139
> 对于所有 $ d \in [0, n) $,求 $ f(i) = d $ 的数量。
2240
>
2341
> 设 $a_i,b_i,c_i$ 最大值为 $k$,$1\leq n\leq10^5,1\leq a_i,b_i,c_i\leq k\leq2\times10^5$。
2442
25-
# 一维偏序
43+
考虑先按照 $a$ 排序,之后就是要求满足 $b_j\leq b_i,c_j\leq c_i$,这就是一个二维限制问题。
44+
45+
考虑树套树解决,树状数组套线段树即可。
46+
47+
但是需要稍微卡一下空间。
48+
```cpp
49+
//#include<bits/stdc++.h>
50+
#include<algorithm>
51+
#include<iostream>
52+
#include<cstring>
53+
#include<iomanip>
54+
#include<cstdio>
55+
#include<string>
56+
#include<vector>
57+
#include<cmath>
58+
#include<ctime>
59+
#include<deque>
60+
#include<queue>
61+
#include<stack>
62+
#include<list>
63+
using namespace std;
64+
constexpr const int N=1e5,V=2e5;
65+
struct element{
66+
int a,b,c;
67+
}a[N+1];
68+
int n,k,ans[N+1];
69+
int size;
70+
struct node{
71+
int l,r;
72+
int lChild,rChild;
73+
int value;
74+
}t[V*80+1];
75+
struct bit{
76+
struct segTree{
77+
int root;
78+
int create(node x){
79+
t[++size]=x;
80+
return size;
81+
}
82+
void up(int p){
83+
t[p].value=t[t[p].lChild].value+t[t[p].rChild].value;
84+
}
85+
void down(int p){
86+
int mid=t[p].l+t[p].r>>1;
87+
if(!t[p].lChild){
88+
t[p].lChild=create({t[p].l,mid});
89+
}
90+
if(!t[p].rChild){
91+
t[p].rChild=create({mid+1,t[p].r});
92+
}
93+
}
94+
void add(int p,int x,int k){
95+
if(t[p].l==t[p].r){
96+
t[p].value+=k;
97+
return;
98+
}
99+
int mid=t[p].l+t[p].r>>1;
100+
if(x<=mid){
101+
if(!t[p].lChild){
102+
t[p].lChild=create({t[p].l,mid});
103+
}
104+
add(t[p].lChild,x,k);
105+
}else{
106+
if(!t[p].rChild){
107+
t[p].rChild=create({mid+1,t[p].r});
108+
}
109+
add(t[p].rChild,x,k);
110+
}
111+
up(p);
112+
}
113+
void add(int x,int k){
114+
add(root,x,k);
115+
}
116+
int query(int p,int x){
117+
if(t[p].r<=x){
118+
return t[p].value;
119+
}
120+
// down(p);
121+
int ans=0;
122+
if(t[p].lChild){
123+
ans=query(t[p].lChild,x);
124+
}
125+
if(t[p].rChild){
126+
if(t[t[p].rChild].l<=x){
127+
ans+=query(t[p].rChild,x);
128+
}
129+
}
130+
return ans;
131+
}
132+
int query(int x){
133+
return query(root,x);
134+
}
135+
}T[V+1];
136+
137+
int lowbit(int x){
138+
return x&-x;
139+
}
140+
void insert(int b,int c,int x){
141+
while(b<=k){
142+
T[b].add(c,x);
143+
b+=lowbit(b);
144+
}
145+
}
146+
int query(int b,int c){
147+
int ans=0;
148+
while(b){
149+
ans+=T[b].query(c);
150+
b-=lowbit(b);
151+
}
152+
return ans;
153+
}
154+
void build(){
155+
for(int i=1;i<=k;i++){
156+
T[i].root=T[i].create({1,k});
157+
}
158+
}
159+
}T;
160+
int main(){
161+
// freopen("test.in","r",stdin);
162+
// freopen("test.out","w",stdout);
163+
164+
ios::sync_with_stdio(false);
165+
cin.tie(0);cout.tie(0);
166+
167+
cin>>n>>k;
168+
T.build();
169+
for(int i=1;i<=n;i++){
170+
cin>>a[i].a>>a[i].b>>a[i].c;
171+
}
172+
sort(a+1,a+n+1,[](element a,element b){
173+
if(a.a!=b.a){
174+
return a.a<b.a;
175+
}else if(a.b!=b.b){
176+
return a.b<b.b;
177+
}else{
178+
return a.c<b.c;
179+
}
180+
});
181+
for(int i=1;i<=n;i++){
182+
int cnt=1;
183+
while(i<n&&a[i+1].a==a[i].a&&a[i+1].b==a[i].b&&a[i+1].c==a[i].c){
184+
i++;
185+
cnt++;
186+
}
187+
T.insert(a[i].b,a[i].c,cnt);
188+
ans[T.query(a[i].b,a[i].c)-1]+=cnt;
189+
}
190+
for(int i=0;i<n;i++){
191+
cout<<ans[i]<<'\n';
192+
}
193+
194+
cout.flush();
195+
196+
/*fclose(stdin);
197+
fclose(stdout);*/
198+
return 0;
199+
}
200+
```

0 commit comments

Comments
 (0)