Educational Codeforces Round 107 (Rated for Div. 2)

Educational Codeforces Round 107 (Rated for Div. 2)

A - Review Site

int main() {
    IOS;
    for (cin >> _; _; --_) {
        cin >> n; int x = 0, y = 0, z = 0;
        rep (i, 1, n) {
            cin >> m;
            if (m == 1) {
                if (x < 0) ++x, ++z;
                else ++y, ++z; 
            } else if (m == 2) {
                if (x > 0) --x;
                else --y;
            } else {
                if (x >= 0) ++x, ++z;
                else if (y >= 0) ++y, ++z;
                else --y;
            }
        }
        cout << z << '\n';
    }
    return 0;
}

B - GCD Length

\(gcd=10^{c - 1}\) 构造就行了

int work(int x) { int c = 0; while (x) ++c, x /= 10; return c; }
 
int main() {
    IOS;
    for (cin >> _; _; --_) {
        int a, b, c, x = 1, y = 1; cin >> a >> b >> c;
        rep (i, 1, a - c) { while (work(x << 1) == work(x)) x <<= 1; x <<= 1; }
        rep (i, 1, b - c) { while (work(y * 3) == work(y)) y *= 3; y *= 3; }
        rep (i, 2, c) x *= 10, y *= 10; 
        cout << x << ' ' << y << '\n';
    }
    return 0;
}

C - Yet Another Card Deck

原本序列放在\([1 + m, n + m]\)

倒序\(m\), 则相当于每次抽一张牌放在\(i\)这个位置,

set维护牌种类颜和位置, 树状维护[1, l]有几张牌

void add(int x, int k) { for (; x <= n + m; x += -x & x) c[x] += k; }
 
int ask(int x) { ll ans = 0; for (; x; x -= -x & x) ans += c[x]; return ans; }
 
int main() {
    IOS; cin >> n >> m; set<PII> st;
    rep (i, 1, n) cin >> _, st.insert({ _, i + m }), add(i + m, 1);
    per (i, m, 1) {
        cin >> _;
        auto it = st.lower_bound({ _, -2e9 });
        cout << ask(it->se) << '\n'; add(it->se, -1); add(i, 1);
        st.erase(it); st.insert({ _, i });
    }
    return 0;
}

D - Min Cost String

贪心拼接就行了

int tr[26][26];
string s = "a";
 
int main() {
    IOS; cin >> n >> m;
    for (int i = 1, j = 0, c = 0; i < n; ++i, c = j) {
        while (~c && tr[s[i - 1] - 'a'][c]) --c;
        if (c == -1) c = ++j;
        if (j >= m) { memset(tr, 0, sizeof tr); j = c = 0; }
        s += 'a' + c; tr[s[i - 1] - 'a'][c] = 1;
    }
    cout << s;
    return 0;
}

E - Colorings and Dominoes

注意到每行(列)的贡献与其他行(列)的贡献互不影响

则可以容斥计算每行每列的贡献

对于每行(列), \(f[i][0/1]\) 表示在当前序列\(i\)放红(蓝)色的\([1, i]\)贡献, 没错每行(列)当中的贡献也是容斥互不影响的

注意要每行(列)最大放砖块就行了, \(O(n)\)

char cs;
vector<VI> a;
VI b;
ll ans, f[N][2], qp[N];

void work(VI& a) {
    int c = 0; ll res = 0;
    rep(i, 1, a.size() - 1)
        if (a[i] && a[i - 1]) {
            f[i][0] = (f[i - 1][1] + f[i - 1][0]) % mod;
            f[i][1] = (f[i - 1][0] + f[i - 2][1] + f[i - 2][0] + qp[++c - 2]) % mod;
        }
        else if (a[i]) f[i][0] = f[i][1] = f[i - 1][0], ++c;
        else f[i][0] = (f[i - 1][0] + f[i - 1][1]) % mod, f[i][1] = 0;
    ans = (ans + qp[k - c] * (f[a.size() - 1][0] + f[a.size() - 1][1]) % mod) % mod;
}

int main() {
    IOS; cin >> n >> m; a.resize(n + 1, VI(m + 1)); qp[0] = 1;
    rep(i, 1, n * m) qp[i] = (qp[i - 1] << 1) % mod;
    rep (i, 1, n) rep (j, 1, m) cin >> cs, a[i][j] = cs == 'o', k += a[i][j];
    rep (i, 1, n) work(a[i]);
    rep (i, 1, m) { b.resize(1); rep(j, 1, n) b.pb(a[j][i]); work(b); }
    cout << ans;
    return 0;
}
posted @ 2021-04-13 12:24  洛绫璃  阅读(150)  评论(0编辑  收藏  举报