传送们 AtCoder Beginner Contest 279
∗ * ∗D - Freefall
Tutorial
求
f
(
x
)
=
B
×
x
+
A
x
+
1
f(x)=B\times x+\frac{A}{\sqrt{x+1}}
f(x)=B×x+x+1A 的最小值。
f
′
(
x
)
=
B
−
1
2
A
(
x
+
1
)
−
2
3
f'(x)=B-\frac{1}{2}A(x+1)^{-\frac{2}{3}}
f′(x)=B−21A(x+1)−32,容易观察出这是一个凹函数,所以其最小值在
x
=
(
A
2
B
)
2
3
−
1
x=(\frac{A}{2B})^{\frac{2}{3}}-1
x=(2BA)32−1 处取到。
Solution
#include <bits/stdc++.h>
#define int long long
#define pii pair<int, int>
#define inf 0x3f3f3f3f
const int N = 3e5 + 7;
using namespace std;
signed main() {
//ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
int a, b;
cin >> a >> b;
int res = pow(1.0 * a / (b * 2), 2.0 / 3.0) - 1;
//注意考虑精度问题
int l = max(0ll, res - 5), r = min(a / b, res + 5);
double ans = a;
for (int i = l; i <= r; i++) ans = min(ans, 1.0 * a / sqrt(i + 1) + b * i);
printf("%.10lf", ans);
}
E - Cheating Amidakuji
Tutorial
维护前后缀和
维护
q
1
(
x
)
q_1(x)
q1(x) 表示经过
1
∽
i
−
1
1\backsim i-1
1∽i−1 的操作后
x
x
x 的位置,
p
1
(
x
)
p_1(x)
p1(x) 表示经过
1
∽
i
−
1
1\backsim i-1
1∽i−1 的操作后第
x
x
x 位上是什么,显然
q
1
(
x
)
q_1(x)
q1(x) 和
p
1
(
x
)
p_1(x)
p1(x) 是互逆的。
同样的,维护
q
2
(
x
)
q_2(x)
q2(x) 表示经过
n
∽
i
+
1
n\backsim i+1
n∽i+1 的操作后
x
x
x 的位置,
p
2
(
x
)
p_2(x)
p2(x) 表示经过
n
∽
i
+
1
n\backsim i+1
n∽i+1 的操作后第
x
x
x 位上是什么,显然
q
2
(
x
)
q_2(x)
q2(x) 和
p
2
(
x
)
p_2(x)
p2(x) 也是互逆的。
则我们要求的即为经过
1
∽
i
−
1
1\backsim i-1
1∽i−1 和
i
+
1
∽
n
i+1\backsim n
i+1∽n 的操作后
1
1
1 的位置,即为
q
2
−
1
(
q
1
(
1
)
)
q_2^{-1}(q_1(1))
q2−1(q1(1)),也即
p
2
(
q
1
(
1
)
)
p_2(q_1(1))
p2(q1(1))。
Solution
#include <bits/stdc++.h>
#define int long long
#define pii pair<int, int>
#define inf 0x3f3f3f3f
const int N = 2e5 + 7;
using namespace std;
int a[N], q1[N], q2[N], p1[N], p2[N];
signed main() {
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
int n, m;
cin >> n >> m;
for (int i = 1; i <= m; i++) cin >> a[i];
for (int i = 1; i <= n; i++) q1[i] = p1[i] = q2[i] = p2[i] = i;
for (int i = m; i; i--) {
swap(q2[p2[a[i]]], q2[p2[a[i] + 1]]);
swap(p2[a[i]], p2[a[i] + 1]);
}
for (int i = 1; i <= m; i++) {
swap(q2[p2[a[i]]], q2[p2[a[i] + 1]]);
swap(p2[a[i]], p2[a[i] + 1]);
cout << p2[q1[1]] << '\n';
swap(p1[a[i]], p1[a[i] + 1]);
swap(q1[p1[a[i]]], q1[p1[a[i] + 1]]);
}
}
∗ * ∗F - BOX
Tutorial
建立并查集,记录每个盒子所对应的树根和每个树根所对应的盒子。
Solution
#include <bits/stdc++.h>
#define int long long
#define pii pair<int, int>
#define inf 0x3f3f3f3f
const int N = 6e5 + 7;
using namespace std;
int fa[N], tre[N], box[N];
int find(int x) {
return fa[x] ? fa[x] = find(fa[x]) : x;
}
signed main() {
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
int n, q, op, x, y;
cin >> n >> q;
for (int i = 1; i <= n; i++) tre[i] = box[i] = i;
int k = n;
while (q--) {
cin >> op;
if (op == 1) {
cin >> x >> y;
if (tre[x]) fa[tre[y]] = tre[x];
else tre[x] = tre[y], box[tre[x]] = x;
tre[y] = 0;
} else if (op == 2) {
cin >> x;
if (tre[x]) fa[++k] = tre[x];
else tre[x] = ++k, box[k] = x;
} else {
cin >> x;
cout << box[find(x)] << "\n";
}
}
}