zoukankan      html  css  js  c++  java
  • Educational Codeforces Round 101 (Rated for Div. 2)

    Educational Codeforces Round 101 (Rated for Div. 2)

    A - Regular Bracket Sequence

    最多有一对 (), 判断完事

    int main() {
        IOS;
        for (cin >> _; _; --_) {
            string s; cin >> s;
            if (s.size() % 2 || s[0] == ')' || s.back() == '(') cout << "NO
    ";
            else cout << "YES
    ";
        }
        return 0;
    }
    

    B - Red and Blue

    贪心找两个序列的最大前缀和

    int main() {
        IOS;
        for (cin >> _; _; --_) {
            cin >> n; int x = 0, y = 0;
            for (int s = 0, i = 1; i <= n; ++i) cin >> k, s += k, umax(x, s);
            cin >> n;
            for (int s = 0, i = 1; i <= n; ++i) cin >> k, s += k, umax(y, s);
            cout << x + y << '
    ';
        }
        return 0;
    }
    

    C - Building a Fence

    按顺序找出当前 i 可以放的最高和最低位置, 再按提议判断即可

    int main() {
        IOS;
        for (cin >> _; _; --_) {
            cin >> n >> k >> m;
            int x = m, y = m; bool f = 1;
            rep (i, 2, n) {
                cin >> m;
                x = min(x + k - 1, m + k - 1);
                y = max(y - k + 1, m);
                if (x < y) f = 0;
            }
            if (y != m || !f) cout << "NO
    ";
            else cout << "YES
    ";
        }
        return 0;
    }
    

    D - Ceil Divisions

    明显能想到一个数用比它大的数变成 1, 但剩下最大数无法处理

    只给你了n + 5, 明显让你在5次之内变成 1, 而 sqrt(n - 1) + 1 刚好 2 次

    然后 sqrt(n - 1) + 1 成为了最大数, 在按上面操作, 而最多开5次根号, 刚刚好(1, 2还不用变呢 n + 3就够了)

    int main() {
        IOS;
        for (cin >> _; _; --_) {
            cin >> n; VI a(1, n);
            while (a.back() != 2) a.pb(sqrt(a.back() - 1) + 1);
            cout << n - 3 + a.size() << '
    ';
            for (int i = n, j = 0; i > 2; --i)
                if (i == a[j]) ++j;
                else cout << i << ' ' << n << '
    ';
            rep (i, 1, a.size() - 1) rep (j, 0, 1) cout << a[i - 1] << ' ' << a[i] << '
    ';
        }
        return 0;
    }
    

    E - A Bit Similar

    一看字符串里找字符串就先把 sam 板子仍上去, 然而1e6 咋办呢

    最多有1e6个字串, 也就是说最多能完全覆盖长度为 log2(1e6) 的01串, 在sam上贪心爆搜完事

    当然肯定有不用sam的方法, div2不怎么考数据结构的, 能用板子直接扔最好了

    struct SAM { //不管是不是多组数据都调用init
        static const int N = 1e6 + 5, M = 2;
        struct node { int fa, len, ne[M]; } tr[N << 1];
        int sz, las;
        void init() {
            rep(i, 1, sz)
                tr[i].len = tr[i].fa = 0, memset(tr[i].ne, 0, sizeof tr[i].ne);
            sz = las = 1;
        }
        void add(int ch) {
            int p = las, cur = las = ++sz;
            tr[cur].len = tr[p].len + 1;
            for (; p && !tr[p].ne[ch]; p = tr[p].fa) tr[p].ne[ch] = cur;
            if (p == 0) { tr[cur].fa = 1; return; }
            int q = tr[p].ne[ch];
            if (tr[q].len == tr[p].len + 1) { tr[cur].fa = q; return; }
            int nq = ++sz; tr[nq] = tr[q]; tr[nq].len = tr[p].len + 1;
            for (; p && tr[p].ne[ch] == q; p = tr[p].fa) tr[p].ne[ch] = nq;
            tr[q].fa = tr[cur].fa = nq;
        }
        void build(char* s) {
            for (int i = 0; s[i]; ++i) add(s[i] - '0');
        }
        bool match(char* s) {
            for (int i = 0, ch = s[i] - '0', p = 1; s[i]; ch = s[++i] - '0')
                if (tr[p].ne[ch]) p = tr[p].ne[ch];
                else return 0;
            return 1;
        }
    } sam;
     
    const int N = 1e6 + 5;
     
    int n, m, _, k;
    char s[N], t[N];
     
    bool check(int x = 0) {
        if (x == k) { t[x] = ''; return !sam.match(t); }
        t[x] = '1';
        if (check(x + 1)) return 1;
        t[x] = '0';
        return check(x + 1);
    }
     
    int main() {
        IOS;
        for (cin >> _; _; --_) {
            cin >> n >> k >> s;
            if (n == k) { 
                cout << "YES
    "; bool f = 0;
                rep (i, 0, n - 2) f = f || s[i] == '0', s[i] = '0';
                if (f) s[n - 1] = '0';
                cout << s << '
    ';
                continue;
            }
            m = log2(n - k) + 1; sam.init(); sam.build(s);
            if (!check()) { cout << "NO
    "; continue; }
            cout << "YES
    ";
            for (int i = 0; t[i]; ++i) t[i] = t[i] - '0' ? '0' : '1';
            rep(i, 0, k - 1) if (!t[i]) t[i] = '0'; t[n] = '';
            cout << t << '
    ';
        }
        return 0;
    }
    

    F - Power Sockets

    还是板子题, 贪心放就好了, 去出没用过的链, 平分两份, 放在树上深度最小的点上, 找就行了

    复杂度 (O(nlog^2n)) 4s够了

    ll c[2][N + 1], ans = 2e18;
     
    void add(int x, ll k) {
        for (int i = x; i <= N; i += -i & i) c[0][i] += k, c[1][i] += x * k;
    }
     
    void add(int l, int r, ll k) { add(l, k); add(r + 1, -k); }
     
    ll ask(int x) {
        ll p = 0, q = 0, f = x + 1;
        for (; x; x -= -x & x) p += c[0][x], q += c[1][x];
        return p * f - q;
    }
     
    ll ask(int l, int r) { return ask(r) - ask(l - 1); }
     
    ll kth(int k) {
        if (ask(N) < k) return 2e18;
        int l = 1, r = N;
        while (l < r) {
            ll mid = l + r >> 1, c;
            if ((c = ask(l, mid)) < k) k -= c, l = mid + 1;
            else r = mid; 
        }
        return l;
    }
     
    int main() {
        IOS; cin >> n >> k; VI a(n);
        for (auto &i : a) cin >> i, --i; sort(all(a));
        add(2, 2 + a.back() >> 1, 1); add(2, 2 + a.back() + 1 >> 1, 1); umin(ans, kth(k));
        per (i, n - 2, 0) {
            int cur = kth(1); add(cur, cur, -1);
            add(cur + 2, 1 + cur + (a[i] >> 1), 1); add(cur + 2, 1 + cur + (a[i] + 1 >> 1), 1);
            umin(ans, kth(k));
        }
        cout << (ans == 2e18 ? -1 : ans);
        return 0;
    }
    
  • 相关阅读:
    2017-2018-2 20155206 《网络对抗技术》 实验六:信息搜集与漏洞扫描
    20155206 Exp5 MSF基础应用
    20155206 实验4 恶意代码分析
    20155206《网络攻防》第三次实验_免杀及其原理
    20155206 Exp2 后门原理与实践
    20155206赵飞 Exp1PC平台逆向破解及Bof基础实践
    J-19 集合对象
    J-18 集合对象
    J-17 集合对象
    J-16 集合对象
  • 原文地址:https://www.cnblogs.com/2aptx4869/p/14248819.html
Copyright © 2011-2022 走看看