前言
今天zty带来的是P1232 [NOI2013] 树的计数,大家给个赞呗, zty开学了,更新是会变少的,这个学期是zty的毕业学期了,过完这学期zty就毕业了
先 赞 后 看 养 成 习 惯
先 赞 后 看 养 成 习 惯
演示用编译器及其标准
Dev C++ 6.7.5 Red panda C++14
正文
P1232 [NOI2013] 树的计数
题目描述
我们知道一棵有根树可以进行深度优先遍历(DFS)以及广度优先遍历(BFS)来生成这棵树的 DFS 序以及 BFS 序。两棵不同的树的 DFS 序有可能相同,并且它们的 BFS 序也有可能相同,例如下面两棵树的 DFS 序都是 1 2 4 5 3
,BFS 序都是 1 2 3 4 5
。
现给定一个 DFS 序和 BFS 序,我们想要知道,符合条件的有根树中,树的高度的平均值。即,假如共有 K K K 棵不同的有根树具有这组 DFS 序和 BFS 序,且他们的高度分别是 h 1 , h 2 , … , h K h_1, h_2, \ldots, h_K h1,h2,…,hK,那么请你输出:
h 1 + h 2 + … + h K K \frac{h_1+h_2+\ldots+h_K}K Kh1+h2+…+hK
输入格式
第一行包含 1 1 1 个正整数 n n n,表示树的节点个数。
第二行包含 n n n 个正整数,是一个 1 … n 1 \ldots n 1…n 的排列,表示树的 DFS 序。
第三行包含 n n n 个正整数,是一个 1 … n 1 \ldots n 1…n 的排列,表示树的 BFS 序。
输入保证至少存在一棵树符合给定的两个序列。
输出格式
输出 1 1 1 个实数,四舍五入保留恰好三位小数,表示树高的平均值。
输入输出样例 #1
输入 #1
5
1 2 4 5 3
1 2 3 4 5
输出 #1
3.500
说明/提示
如果输出文件的答案与标准输出的差不超过 0.001 0.001 0.001,则将获得该测试点上的分数,否则不得分。
数据范围
- 对于 20 % 20\% 20% 的测试数据,满足: n ≤ 10 n \le 10 n≤10;
- 对于 40 % 40\% 40% 的测试数据,满足: n ≤ 100 n \le 100 n≤100;
- 对于 85 % 85\% 85% 的测试数据,满足: n ≤ 2 × 1 0 3 n \le 2 \times 10^3 n≤2×103;
- 对于 100 % 100\% 100% 的测试数据,满足: 2 ≤ n ≤ 2 × 1 0 5 2 \le n \le 2 \times 10^5 2≤n≤2×105。
#include <bits/stdc++.h>
#define int long long
#define _ (int)2e5 + 5
using namespace std;
int n;
int cc;
int x, y;
double ans = 2.0;
array<int, _> bfn, dfn, b, d, c;
signed main() {
scanf("%lld", &n);
c[1]++, c[2]--;
for (int i = 1; i <= n; ++i) {
scanf("%lld", &dfn[i]);
d[dfn[i]] = i;
}
for (int i = 1; i <= n; ++i) {
scanf("%lld", &bfn[i]);
b[bfn[i]] = i;
}
for (int i = 1; i < n; ++i) {
x = bfn[i], y = bfn[i + 1];
if (d[x] > d[y]) {
c[i]++, c[i + 1]--;
ans++;
}
x = dfn[i], y = dfn[i + 1];
if ((!(b[x] > b[y])) && (!(b[x] + 1 == b[y]))) {
//b[x] + 1 < b[y]
c[b[x]]++, c[b[y]]--;
}
}
for (int i = 1; i < n; ++i) {
cc += c[i];
if (!cc) {
ans += 0.5;
}
}
printf("%.3lf\n", ans);
return 0;
}
后记
作者:zty郑桐羽呀
联系方式:(企鹅 3782663736)
兄弟们给个赞呗
先 赞 后 看 养 成 习 惯