• Codeforces Round #678 (Div. 2)


    A

    观察发现, 和顺序无关

    int main() {
        IOS;
        for (cin >> _; _; --_) {
            cin >> n >> m; ll sum = 0;
            rep (i, 1, n) cin >> k, sum += k;
            if (sum == m) cout << "YES
    ";
            else cout << "NO
    ";
        } 
        return 0;
    }
    

    B

    简单构造

    int main() {
        IOS;
        for (cin >> _; _; --_) {
            cin >> n; memset(a, 0, sizeof a);
            if (n & 1) {
                rep (i, 1, n) a[i][i] = 1, a[i][i + 1] = 4;
                a[n][1] = 4;
            }
            else for (int i = 1; i <= n; i += 2) a[i][i] = a[i][i + 1] = a[i + 1][i] = a[i + 1][i + 1] = 1;
            rep (i, 1, n) {
                rep (j, 1, n) cout << a[i][j] << ' ', a[i][j] = 0;
                cout << '
    ';
            }
        } 
        return 0;
    }
    

    C

    按正确的二分走一遍, 找到通过二分比较, 需要多少个 大于 这个数的 和多少个小于这个数的

    然后组合数学

    int n, m, _, k;
    ll inv[N] = {0, 1}, a[N] = {1, 1}, b[N] = {1, 1};
    VI fa;
    
    void init(int n, int p = mod) {
        rep (i, 2, n) {
            inv[i] = (ll)(p - p / i) * inv[p % i] % p;
            a[i] = (ll)a[i - 1] * i % p;
            b[i] = (ll)b[i - 1] * inv[i] % p;
        }
    }
     
    PII work(int k) {
        int l = 1, r = n + 1, x = 0, y = 0;
        while (l < r) {
            int mid = l + r >> 1;
            if (mid <= k) l = mid + 1, ++x;
            else r = mid, ++y;
        }
        return { --x, y };
    }
     
    int main() {
        IOS; init(1e3);
        cin >> n >> m >> k;
        PII p = work(k + 1);
        ll ans = 0;
        if (n - m - p.se >= 0 && m - 1 - p.fi >= 0 && n - p.se - p.fi - 1 >= 0)
              ans = a[n - m] * b[n - m - p.se] % mod * a[m - 1] % mod * b[m - 1 - p.fi] % mod * a[n - p.se - p.fi - 1] % mod;
        cout << ans << '
    ';
        return 0;
    }
    

    D

    题都没读懂, 土匪走的单行道, 居民可以任意走.....原来居民可以任意走啊.....

    int main() {
        IOS; cin >> n;
        vector<ll> a(n + 1), siz(n + 1, 1), from(n + 1);
        rep (i, 2, n) cin >> from[i], siz[from[i]] = 0;
        rep (i, 1, n) cin >> a[i];
        ll ans = 0;
        per (i, n, 1) {
            umax(ans, (a[i] - 1 + siz[i]) / siz[i]);
            a[from[i]] += a[i]; siz[from[i]] += siz[i];
        }
        cout << ans;
        return 0;
    }
    

    E

    找 a[i] 是否可以选入 mex 集

    i 左边存在 1~a[i]-1, 或者 x 右边存在 1~a[i]-1, 或者 两边合在一起存在 1~a[i]-1

    前两种其实都属于最后一种

    最后一种最不好处理, 但我们可以隔空处理, 对于 i 的左右, 我们直接将 i 这个位置转移到 上一次出现 a[i] 的位置 x, 则 x + 1 ~ n就是 i 左右的合集

    剩下的就好做了

    注意特殊处理 1, 只有在存在 a[i] > 1 的时候 1 才能取到

    int h[N], ne[N], a[N], c[N];
    bool v[N];
    
    void add(int x, int k) {
        for (; x <= n; x += -x & x) umin(c[x], k);
    }
    
    int ask(int x) {
        int ans = n;
        for (; x; x -= -x & x) umin(ans, c[x]);
        return ans;
    }
    
    int main() {
        IOS; cin >> n;
        rep (i, 1, n) cin >> a[i], ne[i] = h[a[i]], h[a[i]] = i, c[i] = n;
        rep (i, 1, n) add(i, h[i]);
        rep (i, 2, n + 1) if (ask(i - 1) > h[i]) v[i] = 1;
        per (i, n, 1) {
            add(a[i], ne[i]);
            if (a[i] - 1 && ask(a[i] - 1) > ne[i]) v[a[i]] = 1;
            if (a[i] - 1) v[1] = 1;
        }
        int ans = 0; while (v[++ans]); cout << ans;
        return 0;
    }
    
  • 相关阅读:
    *循环-04. 验证“哥德巴赫猜想”
    循环-03. 求符合给定条件的整数集
    *循环-01. 求整数段和【help】
    分支-15. 日K蜡烛图
    分支-14. 简单计算器
    *分支-13. 计算天数
    *分支-12. 计算火车运行时间
    自我介绍
    JAVA WEB第0课
    Forward团队-爬虫豆瓣top250项目-成员简介与分工
  • 原文地址:https://www.cnblogs.com/2aptx4869/p/13875668.html
Copyright © 2020-2023  润新知