Codeforces Round #574 (Div. 2)

Contest Info


Practice Link

Solved A B C D1 D2 E F
6/7 O O O O O Ø -
  • O through the game
  • Ø After the game by
  • ! I tried but failed
  • - No attempt

Solutions


A. Drinks Choosing

Meaning of the questions:
There \ (n \) personal, everyone likes to eat the first \ (k_i \) kind of candy store is now selling a box of candy is two, the number of boxes to buy a minimum number, that \ (\ left \ lceil \ frac {n} {2} \ right \ rceil \) cartridge, and so that as many people like to eat candy eat their

Ideas:
the like to eat sweets on the same people together, each taking two to give them a box of greed, so that their contribution is full.
The rest must be a maximum of one candy each person likes to eat, then the contribution is the number of boxes remaining.

Code:

#include <bits/stdc++.h>
using namespace std;
 
#define N 1010
int n, k, a[N];
 
int main() {
    while (scanf("%d%d", &n, &k) != EOF) {
        memset(a, 0, sizeof a);
        for (int i = 1, x; i <= n; ++i) {
            scanf("%d", &x);
            ++a[x];
        }
        int res = 0;
        int num = n / 2 + (n & 1);
        for (int i = 1; i <= k; ++i) {
            while (a[i] >= 2 && num > 0) {
                --num;
                a[i] -= 2;
                res += 2;
            }
        }
        printf("%d\n", res + num); 
    }
    return 0;
}

B. Sport Mafia

Meaning of the questions:
There are two modes of operation:

  • If the current box of candy there, you can remove a candy
  • The number of some candy, candy box is placed into the last number of $ 1 + $
    Q eventually given the number of operations \ (n \) and the final number of candy box \ (k \) , had asked during operation how many modes of operation is the first operation.

Ideas:
The obvious answer is \ (I \ in [. 1, n-] \) , and satisfies:
\ [\ the begin {the eqnarray *} \ FRAC {I * (I +. 1)} {2} - (n-- I) = k \ end {eqnarray *} \
] corresponds seeking
\ [\ begin {eqnarray *} \ frac {i ^ 2} {2} + \ frac {3i} {2} - n - k = 0 \ end {eqnarray * } \]
roots of the equation.
Obviously the axis of symmetry of the quadratic equation \ (- \ FRAC. 3} {2} {\) , so \ ([1, n] \ ) roots in the range of only one.
Therefore, to direct violence, because \ (I \) enumeration in an amount of about \ (\ mathcal {O} ( \ sqrt {n}) \)

Code:

#include <bits/stdc++.h>
using namespace std;
 
#define ll long long
ll n, k;
 
ll f(int x) {
    return 1ll * x * (x + 1) / 2;
}
 
int main() {
    while (scanf("%lld%lld", &n, &k) != EOF) {
        for (int i = 1; i <= n; ++i) {
            if (f(i) - (n - i) == k) {
                printf("%lld\n", n - i);
                break;
            }
        }
    }
    return 0;
}

C. Basketball Exercise

Meaning of the questions:
There are two rows of people, each row \ (n \) individuals are now asked to choose among a number of people in the two rows, making them the highest and height, and the following restrictions:

  • The number in each row selected is not adjacent
  • If the selected index increasing

Code:
Consider \ (f [i] [0/1/2 ] \) represents the section \ (I \) column positions, the first row is the selected person, the person or the second row, this row is not selected.
Transfer can be.

Ideas:

#include <bits/stdc++.h>
using namespace std;
 
#define ll long long
#define N 100010
int n;
ll h[N][2], f[N][2];
 
int main() {
    while (scanf("%d", &n) != EOF) {
        for (int i = 1; i <= n; ++i) {
            scanf("%lld", &h[i][0]);
        }
        for (int i = 1; i <= n; ++i) {
            scanf("%lld", &h[i][1]);
        }
        memset(f, 0, sizeof f);
        f[1][0] = h[1][0];
        f[1][1] = h[1][1];
        ll res = 0;
        for (int i = 2; i <= n; ++i) {
            f[i][0] = h[i][0] + f[i - 1][1];
            f[i][1] = h[i][1] + f[i - 1][0];
            if (i > 2) {
                f[i][0] = max(f[i][0], h[i][0] + max(f[i - 2][0], f[i - 2][1]));
                f[i][1] = max(f[i][1], h[i][1] + max(f[i - 2][0], f[i - 2][1]));
            }
        }
        for (int i = 1; i <= n; ++i) {
            for (int j = 0; j < 2; ++j) {
                res = max(res, f[i][j]);
            }
        }
        printf("%lld\n", res);
    }
    return 0;
}

D1. Submarine in the Rybinsk Sea (easy edition)

The meaning of problems:
the definition of blending functions \ (F (a_1a_2 \ cdots a_p, b_1b_2 \ cdots b_q) \) : \
[F (A_1 \ cdots a_p, B_1 \ cdots b_q) = \ left \ {\ the begin {Array} {CCCC} a_1a_2 \ cdots a_ {p - q +1} b_1a_ {p - q + 2} b_2 \ cdots a_ {p - 1} b_ {q - 1} a_pb_p && p \ leq q \\ b_1b_2 \ cdots b_ {q - p } a_1b_ {q - p + 1
} a_2 \ cdots a_ {p - 1} b_ {q - 1} a_pb_q && p <q \ end {array} \ right \]. and then give a sequence \ (a_i \) , Inquiry:
\ [\ the begin {the eqnarray *} \ SUM \ limits_ {I =. 1} ^ n-\ SUM \ limits_ {J =. 1} ^ NF (a_i, a_j) \ BMOD 998 244 353 \ End {the eqnarray *} \]
where ensure \ (a_i \) the same number of digits.

Idea:
Since the same number of digits, then we know that \ (? F (a_i,) \) when \ (a_i \) contributions, and \ (f (?, a_i) \ ) when \ (a_i \) contributions to calculate.

Code:

#include <bits/stdc++.h>
using namespace std;
 
#define ll long long
#define N 100010
const ll p = 998244353;
int n, a[N], len;
 
int getlen(int x) {
    int res = 0;
    while (x) {
        ++res;
        x /= 10;
    }
    return res;
}
 
ll f(ll x) {
    ll tot = 0;
    vector <int> vec;
    while (x) {
        vec.push_back(x % 10);
        x /= 10;
    }
    reverse(vec.begin(), vec.end());
    for (auto it : vec) {
        tot = tot * 10 + it;
        tot = tot * 10 + it;
        tot %= p;   
    }
    return tot * n % p; 
}
 
int main() {
    while (scanf("%d", &n) != EOF) {
        for (int i = 1; i <= n; ++i) {
            scanf("%d", a + i);
        }
        len = getlen(a[1]);
        ll res = 0;
        for (int i = 1; i <= n; ++i) {
            res += f(a[i]);
            res %= p;
        }
        printf("%lld\n", res);
    }
    return 0;
}

D2. Submarine in the Rybinsk Sea (hard edition)

Meaning of the questions:
with \ (D1 \) , but does not guarantee \ (a_i \) the same number of digits.

Ideas:
digits at most \ (10 \) position, direct violence pieces \ (a_i \) corresponding \ (a_j \) number of different bits of contribution can be.
\ (10 ^ 9 \) is a ten-digit number.

Code:

#include <bits/stdc++.h>
using namespace std;
 
#define ll long long
#define N 100010
const ll p = 998244353;
int n, a[N], num[N];
vector <vector<int>> vec;
int sze[20];
 
int getlen(int x) {
    int res = 0;
    while (x) {
        ++res;
        x /= 10;
    }
    return res;
}  
 
ll f(ll x, int a, int b, int n) {
    vector <int> vec, A(22, 0);
    while (x) {
        vec.push_back(x % 10);
        x /= 10;
    }
    reverse(vec.begin(), vec.end());
    int len = a + b; 
    if (a >= b) {
        auto it = vec.begin();
        for (int i = 1; i <= a - b + 1; ++i) {
            A[i] = *it;
            ++it;
        }
        for (int i = a - b + 3; i <= len; i += 2) {
            A[i] = *it;
            ++it;
        }
    } else {
        auto it = vec.begin();
        for (int i = b - a + 1; i <= len; i += 2) {
            A[i] = *it;
            ++it;
        }
    }
//  for (int i = 1; i <= len; ++i) printf("%d%c", A[i], " \n"[i == len]);
    ll tot = 0;
    for (int i = 1; i <= len; ++i) {
        tot = tot * 10 + A[i];
        tot %= p;
    }
    return tot * n % p;
}
 
ll g(ll x, int b, int a, int n) {
    vector <int> vec, A(22, 0);
    while (x) {
        vec.push_back(x % 10);
        x /= 10;
    }
    reverse(vec.begin(), vec.end());
    int len = a + b;
    if (a >= b) {
        auto it = vec.begin();
        for (int i = a - b + 2; i <= len; i += 2) {
            A[i] = *it;
            ++it;
        }
    } else {
        auto it = vec.begin();
        for (int i = 1; i <= b - a; ++i) {
            A[i] = *it;
            ++it;
        }
        for (int i = b - a + 2; i <= len; i += 2) {
            A[i] = *it;
            ++it;
        }
    }
    ll tot = 0;
    for (int i = 1; i <= len; ++i) {
        tot = tot * 10 + A[i];
        tot %= p;
    }
    return tot * n % p;
}
 
int main() {
    while (scanf("%d", &n) != EOF) {
        vec.clear();
        vec.resize(20);
        for (int i = 1; i <= n; ++i) {
            scanf("%d", a + i);
            vec[getlen(a[i])].push_back(a[i]);  
        }
        for (int i = 1; i <= 10; ++i) sze[i] = (int)vec[i].size();
        ll res = 0;
        for (int i = 1; i <= 10; ++i) if (sze[i]) {
            for (auto it : vec[i]) {
                for (int j = 1; j <= 10; ++j) if (sze[j]) {
                    res += f(it, i, j, sze[j]);
                    res %= p;
                    res += g(it, i, j, sze[j]); 
                    res %= p;
                }
            }
        }
        printf("%lld\n", res);
    }
    return 0;
}

E. OpenStreetMap

The meaning of problems:
seeking \ (n \ cdot m \) rectangle \ (a \ cdot b \) the minimum value of all the small rectangle and.

Ideas:
a two-dimensional \ (RMQ \) is hard on. .
Consider complexity affirmative \ (\ mathcal {O} (nm) \) .
We can enumerate vertically lower right corner of the rectangle, and then sideways enumeration.
Consider \ (3000 \) th row of each queue maintains monotonically to a minimum value enumerated, then queue maintains a monotonic \ (a \ cdot b \) a minimum value within the rectangle.
Note that the determination time and add the deleted point.

Code:

#include <bits/stdc++.h>
using namespace std;
 
#define ll long long
#define N 3010
int n, m, a, b;
ll g[N * N], x, y, z;
int B[N][N], l[N], r[N], que[N], L, R;   
 
int get(int x, int y) {
    return (x - 1) * m + y - 1;
}
 
int main() {
    while (scanf("%d%d%d%d", &n, &m, &a, &b) != EOF) {
        L = 1, R = 0;
        for (int i = 1; i <= n; ++i) l[i] = 1, r[i] = 0;
        scanf("%lld%lld%lld%lld", g, &x, &y, &z);
        for (int i = 1; i <= n * m; ++i) g[i] = (g[i - 1] * x + y) % z;
        for (int i = 1; i <= n; ++i) {
            for (int j = 1; j < b; ++j) {
                while (l[i] <= r[i] && g[get(i, j)] < g[B[i][r[i]]]) {
                    --r[i];
                }
                B[i][++r[i]] = get(i, j); 
            }
        }   
        ll res = 0;
        for (int i = 1; i <= a; ++i) {
            while (L <= R && g[B[i][l[i]]] < g[que[R]]) --R; 
            que[++R] = B[i][l[i]];
        }
        for (int j = b; j <= m; ++j) {
            for (int i = 1; i <= n; ++i) {
                while (l[i] <= r[i] && abs(B[i][l[i]] - get(i, j)) >= b) ++l[i];
                while (l[i] <= r[i] && g[get(i, j)] < g[B[i][r[i]]]) --r[i];
                B[i][++r[i]] = get(i, j);
            }
            L = 1, R = 0;
            for (int i = 1; i < a; ++i) {
                while (L <= R && g[B[i][l[i]]] < g[que[R]]) --R;
                que[++R] = B[i][l[i]];
            }
            for (int i = a; i <= n; ++i) {
                while (L <= R && abs(que[L] - get(i, j)) >= (a - 1) * m + b) ++L;
                while (L <= R && g[B[i][l[i]]] < g[que[R]]) --R;
                que[++R] = B[i][l[i]];
                res += g[que[L]];
            }
        }
        printf("%lld\n", res);
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/Dup4/p/11204775.html