记
Δ
=
x
r
s
o
n
−
x
l
s
o
n
,
h
=
y
r
o
o
t
−
y
l
s
o
n
\Delta=xrson-xlson,h=yroot-ylson
Δ=xrson−xlson,h=yroot−ylson,第
i
i
i层的宽度为
l
e
n
i
len_i
leni,有$len_2 =len_1+\Delta,len_3 =len_2+{\Delta \over 2},len_4=len_3+{\Delta \over 4} $ ,即有
l
e
n
k
=
l
e
n
1
+
Δ
+
Δ
2
+
Δ
4
+
.
.
.
+
Δ
(
k
−
1
)
len_k=len_1+\Delta+{\Delta \over 2}+{\Delta \over 4}+...+{\Delta \over (k-1)}
lenk=len1+Δ+2Δ+4Δ+...+(k−1)Δ,后方显然是一个以
Δ
\Delta
Δ为首项,
1
2
1 \over 2
21为公比的等比数列,
l
e
n
1
=
0
len1=0
len1=0,则
l
e
n
k
=
Δ
∗
(
1
−
(
1
2
)
k
−
1
)
(
1
−
1
2
)
=
2
∗
Δ
−
2
2
−
k
Δ
len_k = {\Delta*(1-({1 \over 2})^{k-1}) \over (1-{1\over 2})}=2*\Delta-2^{2-k}\Delta
lenk=(1−21)Δ∗(1−(21)k−1)=2∗Δ−22−kΔ,比较显然的是凸包由树的最左树链和最右树链及所有叶子结点构成的,它的面积为相邻层构成的图形的面积之和,则有
S
=
1
2
∗
h
(
l
e
n
1
+
l
e
n
2
+
l
e
n
2
+
l
e
n
3
+
l
e
n
3
+
l
e
n
4
+
.
.
.
+
l
e
n
k
−
1
+
l
e
n
k
)
{S = {1 \over 2}*h({len_1+len_2+len_2+len_3+len_3+len_4+...+len_{k-1}+len_k})}
S=21∗h(len1+len2+len2+len3+len3+len4+...+lenk−1+lenk)
即有
S
=
1
2
∗
h
(
l
e
n
1
+
2
∗
l
e
n
2
+
2
∗
l
e
n
3
+
.
.
.
+
2
∗
l
e
n
k
−
1
+
l
e
n
k
)
S={1 \over 2}*h({len_1+2*len_2+2*len_3+...+2*len_{k-1}+len_k})
S=21∗h(len1+2∗len2+2∗len3+...+2∗lenk−1+lenk),
l
e
n
1
=
0
len_1=0
len1=0,
化简可得:
S
=
h
∗
(
l
e
n
2
+
l
e
n
3
+
l
e
n
4
.
.
.
+
l
e
n
k
)
+
l
e
n
k
∗
h
2
=
h
∗
(
2
∗
Δ
−
2
2
−
2
Δ
+
2
∗
Δ
−
2
1
−
k
Δ
+
.
.
.
+
2
∗
Δ
−
2
3
−
k
)
+
h
∗
2
Δ
−
2
2
−
k
2
S=h*(len_2+len_3+len_4...+len_k)+{len_k*h \over 2}=h*({2*\Delta-2^{2-2}\Delta+2*\Delta-2^{1-k}\Delta}+...+2*\Delta-2^{3-k})+{h*{2\Delta-2^{2-k}\over 2}}
S=h∗(len2+len3+len4...+lenk)+2lenk∗h=h∗(2∗Δ−22−2Δ+2∗Δ−21−kΔ+...+2∗Δ−23−k)+h∗22Δ−22−k
后面的减数也构成一个以
Δ
\Delta
Δ为首项,
1
2
1 \over 2
21为公比的等比数列,求和化简可得:
S
=
h
∗
(
(
k
−
2
)
Δ
−
(
2
∗
Δ
−
2
3
−
k
Δ
)
)
+
h
∗
2
Δ
−
2
2
−
k
2
S=h*((k-2)\Delta-(2*\Delta-2^{3-k}\Delta))+{h*2\Delta-2^{2-k}\over 2}
S=h∗((k−2)Δ−(2∗Δ−23−kΔ))+2h∗2Δ−22−k
数据范围 T < = 2 e 5 , k < = 1 e 4 T<=2e^5,k<=1e^4 T<=2e5,k<=1e4,且无模数,暴力算 2 x 2^x 2x显然不可行,此题精度要求不算高,因此当 k k k够大时,认为 2 − x 2^{-x} 2−x为0
AcCode:
#include <iostream>
#include <algorithm>
#include <stack>
#include <iomanip>
#include <cstdio>
#define SYNC std::ios::sync_with_stdio(false)
#define CIN std::cin.tie(0);
#define COUT std::cout.tie(0);
double dv[52];
signed main() {
int t; scanf("%d", &t);
dv[0] = 1;
for (int i = 1; i <= 50; i++) dv[i] = dv[i - 1] * 2;
while (t--) {
int k; scanf("%d", &k);
int xroot, yroot, xlson, ylson, xrson, yrson; scanf("%d %d %d %d %d %d", &xroot, &yroot, &xlson, &ylson, &xrson, &yrson);
double h = 1.0 * yroot - ylson, q = 1.0 * xrson - xlson;
double ans = 0;
if (k == 2) {
ans = h * q / 2.0;
printf("%.3lf\n", ans);
continue;
}
double add1 = (k - 2.0) * 2.0 * q;
double sub1 = 2.0 * q - ((k < 50) ? q / dv[k - 3] : 0);
add1 = h * (add1 - sub1);
double add2 = q * h;
double sub3 = (k < 50) ? q * h / dv[k - 1] : 0;
ans = add1 + add2 - sub3;
printf("%.3lf\n", ans);
}
}
本文介绍了一种计算二叉树宽度变化规律及其在求取凸包面积中的应用,通过等比数列求和技巧,给出了面积的公式。解决了一个涉及树结构、等比数列和面积计算的实际问题。
763

被折叠的 条评论
为什么被折叠?



