Educational Codeforces Round 155 ABCD 题解 | JorbanS

A-Rigged!

int solve() {
    cin >> n;
    for (int i = 0; i < n; i ++) cin >> w[i] >> t[i];
    for (int i = 1; i < n; i ++)
        if (w[i] >= w[0] && t[i] >= t[0])
            return -1;
    return w[0];
}

B-Chips on the Board

ll solve() {
    cin >> n;
    int minA = 1e9, minB = 1e9;
    ll sumA = 0, sumB = 0;
    for (int i = 0; i < n; i ++) {
        int x; cin >> x;
        minA = min(minA, x);
        sumA += x;
    }
    for (int i = 0; i < n; i ++) {
        int x; cin >> x;
        minB = min(minB, x);
        sumB += x;
    }
    ll res = min((ll)minA * n + sumB, (ll)minB * n + sumA);
    return res;
}

C-Make it Alternating

题意 给定 01 01 01 串,删除一些 0 , 1 0,1 0,1,使得原串变成 0 , 1 0,1 0,1 交替的串,问要进行多少次操作和有多少种删除方式(每次删除的位置不同即不同删除方式)

题解

对于一个复杂 01 01 01 串,将其分解成若干纯 0 0 0 串和纯 1 1 1 串,每个纯 0 0 0 串或纯 1 1 1 串,选择保留一个,因此是 C n 1 = n = 串长 C_n^1=n=串长 Cn1=n=串长

将要删除的 01 01 01 按顺序排列成新的串,此时串中的每个值是 0 0 0 1 1 1 已经不重要,因为他们具有一个共同属性,都要被删除,而现在要决定顺序

对于单独的一个长度为 n n n 的串(无需考虑 0 , 1 0,1 0,1 本身)

n = 2 n=2 n=2 时,xx,有 1, 2 两种选择, f ( 2 ) = 2 f(2)=2 f(2)=2

n = 3 n=3 n=3 时,xxx,对于第一次操作有 123 三种选择,对于后续的操作,和 n = 2 n=2 n=2 一致, f ( 3 ) = 3 ⋅ f ( 2 ) f(3)=3·f(2) f(3)=3f(2)

……,类似的,当长度为 n n n 时,对于第一次操作有 n n n 种选择,对于后续的操作有 f ( n − 1 ) f(n -1) f(n1) 种选择,因此一共有 f ( n ) = n ⋅ f ( n − 1 ) f(n)=n·f(n-1) f(n)=nf(n1) 种选择

因此对于长度为 n n n 的单独的全 0 0 0 串或全 1 1 1 串,有 n ! n! n! 种选择方式

综上对于每个纯 0 0 0 串或纯 1 1 1 串,都要选择保留一个,即 C n 1 = n = 串长 C_n^1=n=串长 Cn1=n=串长。而整体有 n ! n! n! 种删除方式,因此答案为 ( ∑ l e n − n ) ! ∏ l e n (\sum len-n)!\prod len (lenn)!len

void solve() {
    string s; cin >> s;
    int n = s.size();
    ll RES = n - 1, res = 1, cnt = 1;
    for (int i = 1; i < n; i ++) {
        if (s[i] == s[i - 1]) cnt ++;
        else {
            (res *= cnt) %= mod;
            cnt = 1, RES --;
        }
    }
    res = res * cnt % mod * fac[RES] % mod;
    cout << RES << ' ' << res << endl;
}

D-Sum of XOR Functions

题意 n n n 个非负数的序列 a a a,计算 ∑ l = 1 n ∑ r = l n ⊕ i = l r a i ⋅ ( r − l + 1 ) ( m o d 998244353 ) \sum_{l=1}^{n} \sum_{r=l}^{n} \oplus_{i=l}^ra_i \cdot (r - l + 1)\pmod{998244353} l=1nr=lni=lrai(rl+1)(mod998244353)

题解 单独考虑每一位,分别进行计算。对于每一位,转化成求一个长度为 n n n 01 01 01 串的异或值为 1 1 1 的子串长度之和。在遍历的过程中维护即可

m [ i ] m[i] m[i] 表示当前有多少个 i i i

int solve() {
    int n; cin >> n;
    for (int i = 1; i <= n; i ++) cin >> a[i];
    int res = 0;
    for (int i = 30; i >= 0; i --) {
        (res <<= 1) %= mod;
        int t[2] = {1}, m[2] = {1};
        int XOR = 0;
        for (int j = 1; j <= n; j ++) {
            XOR ^= a[j] >> i & 1;
            m[XOR] ++;
            (res += t[!XOR]) %= mod;
            (t[0] += m[0]) %= mod;
            (t[1] += m[1]) %= mod;
        }
    }
    return res;
}

你可能感兴趣的:(OI,题解,算法)