AtCoder Beginner Contest 279 补题报告

传送们 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+1 A 的最小值。
f ′ ( x ) = B − 1 2 A ( x + 1 ) − 2 3 f'(x)=B-\frac{1}{2}A(x+1)^{-\frac{2}{3}} f(x)=B21A(x+1)32,容易观察出这是一个凹函数,所以其最小值在 x = ( A 2 B ) 2 3 − 1 x=(\frac{A}{2B})^{\frac{2}{3}}-1 x=(2BA)321 处取到。

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 1i1 的操作后 x x x 的位置, p 1 ( x ) p_1(x) p1(x) 表示经过 1 ∽ i − 1 1\backsim i-1 1i1 的操作后第 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 ni+1 的操作后 x x x 的位置, p 2 ( x ) p_2(x) p2(x) 表示经过 n ∽ i + 1 n\backsim i+1 ni+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 1i1 i + 1 ∽ n i+1\backsim n i+1n 的操作后 1 1 1 的位置,即为 q 2 − 1 ( q 1 ( 1 ) ) q_2^{-1}(q_1(1)) q21(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";
        }
    }
}

 

G、Ex待补

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值