Educational Codeforces Round 22

Educational Codeforces Round 22

艰难
https://codeforces.com/contest/813

A. The Contest

#include <bits/stdc++.h>
#define ll long long

using namespace std;
const int N = 1005;
ll n, m, sum, x;

int main () {
    cin >> n;
    for (int i = 1; i <= n; i++)    cin >> x, sum += x;
    cin >> m;
    for (int i = 1; i <= m; i++) {
        ll l, r;
        cin >> l >> r;
        if (r >= sum) {
            cout << max (sum, l);
            return 0;
        }
    }
    cout << -1;
}

//贪心
//前缀和+差分

B. The Golden Age

直接枚举,数据非常极端以至于边界判断很严格,稍微多乘一次就会溢出!!!!WA了114514次

#include <bits/stdc++.h>
#define int long long
#define ll long long

using namespace std;

signed main () {
    ll x, y, l, r;
    cin >> x >> y >> l >> r;
    set<ll> s;
    s.insert (l - 1), s.insert (r + 1);
    for (int a = 1; ; a *= x) {
        for (int b = 1; ; b *= y) {
            ll n = a + b;
            if (n >= l && n <= r)    s.insert (n);
            if (r / b < y)      break;
        }
        if (r / a < x)  break;
    }
    //for (auto i : s)    cout << i << ' ';   cout << endl;
    ll ans = 0;
    for (auto it = s.begin (); it != s.end (); it++) {
        if (it == s.begin ())   continue;
        ans = max (ans, *it - *(prev(it)) - 1);
    }
    cout << ans << endl;
}

//呜呜只能想到暴力
//优化: 幂指数增长很快, 所以是有限的

C. The Tag Game

B分两种情况:一直往下跳 / 往回走一下再跳到别的地方
故要两个数组:dep记录深度之差(路径长度),down记录当前分支往下的最大深度,从b点开始搜,记录最大值。注意处理跳上来就碰到的情况。

#include <bits/stdc++.h>

using namespace std;
const int N = 2e5 + 5, M = N * 2;
int h[N], ne[M], e[M], idx;
int n, m, dep[N], ans, down[N], p[N];

void add (int a, int b) {
    e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
}

void dfs (int u, int fa) {
    dep[u] = dep[fa] + 1;
    p[u] = fa; //记录前驱,往前跳
    for (int i = h[u]; ~i; i = ne[i]) {
        int j = e[i];
        if (j == fa)    continue;
        ans = max (ans, dep[j]);
        dfs (j, u);
        down[u] = max(down[u], down[j] + 1); //往下走最远能走去哪
    }
}


void dfs2 (int u) {
    if (u == -1)    return ; //re
    if (dep[m] - dep[u] >= dep[u] - dep[1])   return ;//转弯之前遇见
    ans = max (ans, 2 * (dep[u] - dep[1] + down[u]));
    dfs2 (p[u]);
}

int main () {
    memset (h, -1, sizeof h);
    cin >> n >> m;  
    int fm = 1;
    for (int i = 1; i < n; i++) {
        int a, b;
        cin >> a >> b;
        add (a, b), add (b, a);
    }
    dfs (1, -1);
    ans = dep[m] - dep[1];
    dfs2 (m);
    //for (int i = 1; i <= n; i++)    cout << dep[i] << ' ';  cout << endl;
    cout << ans;
}

//当前分支往下的最大深度

D. Two Melodies

E. Army Creation

F. Bipartite Checking

posted @ 2023-02-23 21:34  Sakana~  阅读(10)  评论(0编辑  收藏  举报