AtCoder Beginner Contest 340

A - Arithmetic Progression

#include<bits/stdc++.h>

using namespace std;

using i32 = int32_t;
using i64 = long long;
using i128 = __int128;
using ldb = long double;

#define int i64

using vi = vector<int>;

using pii = pair<int, int>;
using vii = vector<pii>;

const int inf = 1e9, INF = 1e18;
const int mod = 998244353;
const vi dx = {0, 0, 1, -1}, dy = {1, -1, 0, 0};


i32 main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int a, b, d;
    cin >> a >> b >> d;

    for (int i = a; i <= b; i += d) cout << i << " ";
    return 0;
}

B - Append

#include<bits/stdc++.h>

using namespace std;

using i32 = int32_t;
using i64 = long long;
using i128 = __int128;
using ldb = long double;

#define int i64

using vi = vector<int>;

using pii = pair<int, int>;
using vii = vector<pii>;

const int inf = 1e9, INF = 1e18;
const int mod = 998244353;
const vi dx = {0, 0, 1, -1}, dy = {1, -1, 0, 0};

i32 main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int q;
    cin >> q;
    vi a;
    for( int op , x ; q ; q--){
        cin >> op >> x;
        if( op == 1 )  a.push_back(x);
        else cout << *(a.end() - x) << "\n";
    }
    return 0;
}

C - Divide and Divide

\(f[x]\)表示移除\(x\)的代价,因此\(f[x]=x+f[\left \lfloor \frac x 2 \right \rfloor ]+f[\left \lceil \frac x 2 \right \rceil ]\)。因此很容易想到递归的求解即可,这里采用了记忆法剪枝

#include<bits/stdc++.h>

using namespace std;

using i32 = int32_t;
using i64 = long long;
using i128 = __int128;
using ldb = long double;

#define int i64

using vi = vector<int>;
using pii = pair<int, int>;
using vii = vector<pii>;

const int inf = 1e9, INF = 1e18;
const int mod = 998244353;
const vi dx = {0, 0, 1, -1}, dy = {1, -1, 0, 0};

map<int,int> f;

int calc( int n ){
    if( f.count(n) ) return f[n];
    int x = n / 2 , y = n - x;
    return f[n] = n + calc(x) + calc(y);
}

i32 main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int n;
    cin >> n;
    f[1] = 0;
    cout << calc( n );
    return 0;
}

D - Super Takahashi Bros.

根据题目描述可以一张有向图,每次根据读入的\(a,b,x\)可以得到\((i,i+1,a),(i,x,b)\)两条边,因此求一下最短路即可。

#include<bits/stdc++.h>

using namespace std;

using i32 = int32_t;
using i64 = long long;
using i128 = __int128;
using ldb = long double;

#define int i64

using vi = vector<int>;
using pii = pair<int, int>;
const int inf = 1e9, INF = 1e18;
const int mod = 998244353;
const vi dx = {0, 0, 1, -1}, dy = {1, -1, 0, 0};

i32 main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int n;
    cin >> n;
    vector<vector<pii>> e(n + 1);
    for (int i = 1, a, b, x; i < n; i++) {
        cin >> a >> b >> x;
        e[i].emplace_back(i + 1, a);
        e[i].emplace_back(x, b);
    }
    vi dis(n + 1, INF);
    dis[1] = 0;
    priority_queue<pii, vector<pii>, greater<pii>> q;
    q.emplace(0, 1);
    vi vis(n + 1);
    for (; not q.empty();) {
        auto [d, x] = q.top();
        q.pop();
        if (vis[x]) continue;
        vis[x] = 1;
        for (auto [y, w]: e[x]) {
            if (vis[y]) continue;
            if (d + w >= dis[y]) continue;
            dis[y] = d + w;
            q.emplace(dis[y], y);
        }
    }
    cout << dis[n] << "\n";
    return 0;
}

E - Mancala 2

这道题目实际上要实现的是一个区间修改,单点查询的数据数据结构。我们要注意的是放球的时候不能暴力的放,要计算出整体放球数量以及哪些区间额外的放了一个球

#include <bits/stdc++.h>

using namespace std;

using i32 = int32_t;
using i64 = long long;
using i128 = __int128;
using ldb = long double;

#define int i64

using vi = vector<int>;

using pii = pair<int, int>;
using vii = vector<pii>;

const int inf = INT_MAX, INF = 1e18;
const int mod = 998244353;

struct Node {
    int l, r, value, add;
    Node *left, *right;

    Node(int l, int r, int value, int add, Node *left, Node *right) :
            l(l), r(r), value(value), add(add), left(left), right(right) {};
} *root;

vi a;

Node *build(int l, int r) {
    if (l == r) return new Node(l, r, a[l], 0, nullptr, nullptr);
    int mid = (l + r) >> 1;
    Node *left = build(l, mid), *right = build(mid + 1, r);
    return new Node(l, r, left->value + right->value, 0, left, right);
}

void mark(int v, Node *cur) {
    cur->add += v;
    cur->value += v * (cur->r - cur->l + 1);
}

void pushdown(Node *cur) {
    if (cur->add == 0) return;
    mark(cur->add, cur->left), mark(cur->add, cur->right);
    cur->add = 0;
}

void modify(int l, int r, int v, Node *cur) {
    if (l > cur->r || r < cur->l) return;
    if (l <= cur->l && r >= cur->r) {
        mark(v, cur);
        return;
    }
    pushdown(cur);
    int mid = (cur->l + cur->r) >> 1;
    if (l <= mid) modify(l, r, v, cur->left);
    if (r > mid) modify(l, r, v, cur->right);
    cur->value = cur->left->value + cur->right->value;
    return;
}

int query(int l, int r, Node *cur) {
    if (l <= cur->l && r >= cur->r) return cur->value;
    pushdown(cur);
    int mid = (cur->l + cur->r) >> 1, res = 0;
    if (l <= mid) res += query(l, r, cur->left);
    if (r > mid) res += query(l, r, cur->right);
    return res;

}


int32_t main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int n, m;
    cin >> n >> m;
    a.resize(n);
    for (auto &i: a) cin >> i;
    root = build(0, n - 1);
    for (int b, x, y; m; m--) {
        cin >> b;
        x = query(b, b, root);
        modify(b, b, -x, root);
        y = x / n, x %= n;
        if (y > 0) modify(0, n - 1, y, root);
        if (b + x < n) modify(b + 1, b + x, 1, root);
        else {
            modify(b + 1, n - 1, 1, root);
            modify(0, (b + x) % n, 1, root);
        }
    }
    for (int i = 0; i < n; i++)
        cout << query(i, i, root) << " ";
    cout << "\n";
    return 0;
}

F - S = 1

首先根据向量外积计算三角形面积的公式可以得出\(\frac 12 |Bx-Ay|=1\)

因为这里允许范围包含负数,所以上市有解这一定有\(Bx-Ay=2\)有解。

因此我们要解出这个方程的任意整数解即可,这里就是套用扩展欧几里得的板子即可。

但是要注意的是如果\(A,B\)其中有任意值为零的情况,则解的三角形的一定是短边1长边2的直角三角形,要特判这种情况是否存在。

#include<bits/stdc++.h>

using namespace std;

using i32 = int32_t;
using i64 = long long;
using i128 = __int128;
using ldb = long double;

#define int i64

using vi = vector<int>;

using pii = pair<int, int>;
using vii = vector<pii>;

const int inf = 1e9, INF = 1e18;
const int mod = 998244353;
const vi dx = {0, 0, 1, -1}, dy = {1, -1, 0, 0};

int exgcd(int a, int b, int &x, int &y) {
    if (b == 0) {
        x = 1, y = 0;
        return a;
    }
    int d = exgcd(b, a % b, x, y);
    int z = x;
    x = y, y = z - y * (a / b);
    return d;
}

i32 main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int a, b, d, x, y;
    cin >> a >> b;
    if (a == 0) {
        b = abs(b);
        if (b <= 2) cout << 2 / b << " 0\n";
        else cout << "-1\n";
        return 0;
    } else if (b == 0) {
        a = abs(a);
        if (a <= 2) cout << "0 " << 2 / a << "\n";
        else cout << "-1\n";
        return 0;
    }
    d = exgcd(b, -a, x, y);
    if (2 % d == 0) {
        x *= 2 / d, y *= 2 / d;
        cout << x << " " << y << "\n";
    } else cout << "-1\n";
    return 0;
}
posted @ 2024-02-18 17:26  PHarr  阅读(9)  评论(0编辑  收藏  举报