[Explanations] [Codeforces] Codeforces Round # 602 (Div. 1) Brief explanations

A

The meaning of problems

  • Each containing a given \ (\ frac n2 \) brackets a sequence of left and right parentheses

  • Each time a sequence of intervals may be flipped

  • A request does not exceed \ (n-\) times the program operation, after the operation is completed such that the sequence in parentheses is legal sequence, and exactly \ (K \) prefix is valid sequence brackets

  • Multiple sets of data, all the data \ (n \) and no more than \ (2000 \)

Practices: Construction

  • Generating a random legitimate target sequence, such as \ (k-1 \) th ()phase followed by the \ (\ frac n2-k + 1 \) th (and \ (\ frac n2-k + 1 \) one)

  • In order from left to right to check for the position \ (i \) if the target sequence is not the same as looking at the right side of a \ (j \) makes the current sequence of \ (j \) elements of the target sequence \ (i \) equal elements, and inversion interval \ ([i, j] \ )

  • \ (O (n ^ 2) \)

Code

#include <bits/stdc++.h>

template <class T>
inline void read(T &res)
{
    res = 0; bool bo = 0; char c;
    while (((c = getchar()) < '0' || c > '9') && c != '-');
    if (c == '-') bo = 1; else res = c - 48;
    while ((c = getchar()) >= '0' && c <= '9')
        res = (res << 3) + (res << 1) + (c - 48);
    if (bo) res = ~res + 1;
}

const int N = 2005;

int n, k, m, l[N], r[N];
char s[N], tar[N];

void work()
{
    read(n); read(k);
    scanf("%s", s + 1);
    for (int i = 1; i < k; i++)
        tar[i * 2 - 1] = '(', tar[i * 2] = ')';
    for (int i = 1; i <= n / 2 - k + 1; i++)
        tar[(k - 1) * 2 + i] = '(', tar[(k - 1) * 2 + n / 2 - k + 1 + i] = ')';
    m = 0;
    for (int i = 1; i <= n; i++)
    {
        if (s[i] == tar[i]) continue;
        int p;
        for (int j = i; j <= n; j++)
            if (s[j] == tar[i]) p = j;
        l[++m] = i; r[m] = p;
        for (int j = i, k = p; j < k; j++, k--) std::swap(s[j], s[k]);
    }
    printf("%d\n", m);
    for (int i = 1; i <= m; i++) printf("%d %d\n", l[i], r[i]);
}
int main()
{
    int T; read(T);
    while (T--) work();
    return 0;
}

B1 & B2

The meaning of problems

  • Given a length \ (n-\) sequence \ (A \)

  • The definition of "length \ (k \) the optimal sequence" means the length \ (k \) elements and the largest sub-sequence, if there are multiple elements and then take the largest lexicographically smallest

  • \ (m \) group query, each given \ (K \) and \ (POS \) presents to ask length \ (K \) of sub-optimal sequence \ (POS \) number

  • \ (1 \ the a_i \ 10 ^ 9 \) , \ (1 \ the pos \ k \ k \)

  • Easy Version: \ (1 \ n, m \ 100 \)

  • Hard Version:\(1\le n,m\le 2\times10^5\)

Practices: Piggy + on Fenwick tree half

  • Apparently the optimal policy is the maximum number of each election, more than the maximum number of take minimum subscript

  • For Easy Version, you can answer questions after each seek out the sub-sequence

  • For the Hard Version, simply by asking offline \ (k \) after sorting continually put to the collection index for every query of the current collection \ (pos \) small value can be achieved in half on Fenwick tree

Code (Hard Version)

#include <bits/stdc++.h>

template <class T>
inline void read(T &res)
{
    res = 0; bool bo = 0; char c;
    while (((c = getchar()) < '0' || c > '9') && c != '-');
    if (c == '-') bo = 1; else res = c - 48;
    while ((c = getchar()) >= '0' && c <= '9')
        res = (res << 3) + (res << 1) + (c - 48);
    if (bo) res = ~res + 1;
}

const int N = 2e5 + 5;

int n, m, a[N], p[N], A[N], ans[N];

struct query
{
    int th, id;
};

std::vector<query> que[N];

inline bool comp(const int &x, const int &y)
{
    return a[x] > a[y] || (a[x] == a[y] && x < y);
}

void change(int x, int v)
{
    for (; x <= n; x += x & -x)
        A[x] += v;
}

int kth(int k)
{
    int res = 0, x = 0;
    for (int i = 19; i >= 0; i--)
        if (x + (1 << i) <= n && res + A[x + (1 << i)] < k)
            x += 1 << i, res += A[x];
    return x + 1;
}

int main()
{
    int x, y;
    read(n);
    for (int i = 1; i <= n; i++) read(a[i]), p[i] = i;
    std::sort(p + 1, p + n + 1, comp);
    read(m);
    for (int i = 1; i <= m; i++)
    {
        read(x); read(y);
        que[x].push_back((query) {y, i});
    }
    for (int i = 1; i <= n; i++)
    {
        change(p[i], 1);
        for (int j = 0; j < que[i].size(); j++)
            ans[que[i][j].id] = a[kth(que[i][j].th)];
    }
    for (int i = 1; i <= m; i++) printf("%d\n", ans[i]);
    return puts(""), 0;
}

C

The meaning of problems

  • Of a given .and Xconstituted \ (n \ times m \) matrix

  • Seeking a maximum \ (T \) such that a presence of .and Xa matrix composed of \ (A \)

  • Repeat \ (T \) times for \ (A \) all of the upper X, to its centered \ (3 \ times3 \) All elements in the matrix have becomeX

  • Such \ (T \) after the end of operations to get the original matrix, and any one operation before without any Xmatrix on the boundary (i.e., assuming that the matrix is infinite, and given \ (n \ times m \) region addition of all ., the operation is complete \ (T \) after a given time \ (n \ times m \) outside of the region must all .)

  • The output of this \ (T \) and a valid \ (A \) matrix

  • \ (1 \ the nm \ 10 ^ 6 \)

Practice: half of a two-dimensional prefix + + greed and

  • Consider this dichotomy \ (T \)

  • A position to put Xthe original matrix to that position as the center of the side length \ (2T + 1 \) within the square are allX

  • And a position obviously can Fangjiu Fang

  • According to this principle generates a \ (A \) matrix after checking each original matrix Xwhether the can is covered

  • Analyzing the side length of a certain position as the center of \ (2T + 1 \) within the square are all X, and a judgment of the original matrix Xwhether is covered, and can be achieved using two-dimensional prefix

  • Use an array of vectordeposit

  • \(O(nm\log\min(n,m))\)

Code

#include <bits/stdc++.h>

template <class T>
inline T Min(const T &a, const T &b) {return a < b ? a : b;}

template <class T>
inline T Max(const T &a, const T &b) {return a > b ? a : b;}

const int N = 1e6 + 5;

int n, m;

std::string s[N];
std::vector<int> sum[N], s2[N];
std::vector<char> ans[N];

int sum1(int l, int r, int x, int y)
{
    return sum[r][y] - sum[l - 1][y] - sum[r][x - 1] + sum[l - 1][x - 1];
}

int sum2(int l, int r, int x, int y)
{
    return s2[r][y] - s2[l - 1][y] - s2[r][x - 1] + s2[l - 1][x - 1];
}

bool check(int mid)
{
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++)
            s2[i][j] = sum1(Max(1, i - mid), Min(n, i + mid),
                Max(1, j - mid), Min(m, j + mid)) == 1ll * (mid * 2 + 1)
                    * (mid * 2 + 1);
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++)
            ans[i][j] = s2[i][j] ? 'X' : '.', s2[i][j] += s2[i][j - 1];
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++)
            s2[i][j] += s2[i - 1][j];
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++)
            if ((sum2(Max(1, i - mid), Min(n, i + mid),
                Max(1, j - mid), Min(m, j + mid)) > 0) ^ (s[i - 1][j - 1] == 'X'))
                    return 0;
    return 1;
}

int main()
{
    std::cin >> n >> m;
    for (int i = 0; i < n; i++) std::cin >> s[i];
    for (int i = 0; i <= m; i++) sum[0].push_back(0);
    for (int i = 1; i <= n; i++)
    {
        sum[i].push_back(0);
        for (int j = 1; j <= m; j++)
            sum[i].push_back(sum[i][j - 1] + (s[i - 1][j - 1] == 'X'));
    }
    for (int j = 1; j <= m; j++)
        for (int i = 1; i <= n; i++)
            sum[i][j] += sum[i - 1][j];
    for (int i = 0; i <= n; i++)
        for (int j = 0; j <= m; j++)
            s2[i].push_back(0), ans[i].push_back(0);
    int l = 0, r = n * m;
    while (l <= r)
    {
        int mid = l + r >> 1;
        if (check(mid)) l = mid + 1;
        else r = mid - 1;
    }
    std::cout << r << std::endl;
    check(r);
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= m; j++) putchar(ans[i][j]);
        puts("");
    }
    return 0;
}

D1 & D2

The meaning of problems

  • Given a length \ (n-\) sequence \ (H \) , each number is \ ([1, k] \ ) integer in

  • Seeking the number of length \ (n-\) of each number is \ ([1, k] \ ) sequences within integers \ (A \) , such that:

  • \[\sum_{i=1}^n[a_i=h_i]<\sum_{i=1}^n[a_i=h_{i\bmod n+1}]\]

  • The answer to \ (998 244 353 \) modulo

  • \ (1 \ k \ 10 ^ 9 \)

  • Easy Version: \ (1 \ n \ 2000 \)

  • Hard Version: \ (1 \ n \ 2 \ times10 ^ 5 \)

Practice: combinatorics

  • First formula in a different wording

  • \[\sum_{i=1}^n([a_i=h_{i\bmod n+1}]-[a_i=h_i])>0\]

  • Readily available for each \ (I \) , if the \ (h_i = h_ {i \ bmod n + 1} \) then \ ([a_i = h_ {i \ bmod n + 1}] - [a_i = h_i] \ ) is always equal to \ (0 \)

  • Therefore, we need only consider meeting \ (h_i \ neq h_ {i \ bmod n + 1} \) a \ (I \) , provided such \ (I \) have \ (m \) a, multiplied by the final answer \ (k ^ {nm} \) to

  • Readily available, if \ (H_i \ NEQ H_ {I \ BMOD n-+ 1} \) , then the \ ([a_i = h_ {i \ bmod n + 1}] - [a_i = h_i] \) have \ (1 \ ) ways to obtain \ (1 \) , \ (1 \) ways to obtain \ (- 1 \) , \ (K-2 \) made ways \ (0 \)

  • For Easy Version directly \ (O (^ n-2) \) the DP

  • Hard Vers considered for this enumeration \ (m \) th formulas formulas is not how many \ (0 \) (referred to as \ (S \) a), there is problem into \ (S \) number each number can take \ (1 \) or \ (- 1 \) , the summation is greater than \ (0 \) of the program number, the last by the \ ((k-2) ^ {ms} \)

  • For easy to get \ (S \) number and greater than \ (0 \) program and less than \ (0 \) solution is symmetrical, so with \ (2 ^ s \) subtracting equal \ ( 0 \) divided by the number of programs after the \ (2 \) can be, so the answer is:

  • \[k^{n-m}\sum_{i=1}^m\frac{2^i-[i\bmod 2=0]\binom{i}{\frac i2}}2(k-2)^{m-i}\]

  • \ (O (n) \)

Code

#include <bits/stdc++.h>

template <class T>
inline void read(T &res)
{
    res = 0; bool bo = 0; char c;
    while (((c = getchar()) < '0' || c > '9') && c != '-');
    if (c == '-') bo = 1; else res = c - 48;
    while ((c = getchar()) >= '0' && c <= '9')
        res = (res << 3) + (res << 1) + (c - 48);
    if (bo) res = ~res + 1;
}

const int N = 2e5 + 5, rqy = 998244353;

int n, k, h[N], pw[N], p2[N], fac[N], inv[N], dif, ans;

int C(int n, int m)
{
    return 1ll * fac[n] * inv[m] % rqy * inv[n - m] % rqy;
}

int main()
{
    int pw2 = 1;
    read(n); read(k);
    pw[0] = p2[0] = fac[0] = inv[0] = inv[1] = 1;
    for (int i = 1; i <= n; i++)
    {
        read(h[i]);
        pw[i] = 1ll * pw[i - 1] * k % rqy;
        p2[i] = 1ll * p2[i - 1] * (k - 2) % rqy;
        fac[i] = 1ll * fac[i - 1] * i % rqy;
    }
    for (int i = 2; i <= n; i++)
        inv[i] = 1ll * (rqy - rqy / i) * inv[rqy % i] % rqy;
    for (int i = 2; i <= n; i++) inv[i] = 1ll * inv[i] * inv[i - 1] % rqy;
    for (int i = 1; i <= n; i++)
        if (h[i] != h[i % n + 1]) dif++;
    for (int i = 1; i <= dif; i++)
    {
        pw2 = (pw2 + pw2) % rqy;
        int delta = pw2;
        if (!(i & 1)) delta = (delta - C(i, i >> 1) + rqy) % rqy;
        delta = 499122177ll * delta % rqy;
        ans = (1ll * delta * C(dif, i) % rqy * p2[dif - i] % rqy
            * pw[n - dif] + ans) % rqy;
    }
    return std::cout << ans << std::endl, 0;
}

E

The meaning of problems

  • Given a \ (n-\) array elements \ (A \) , each number is \ ([1, n] \ ) integer in

  • Can select each operation part of the element of the array will lose their \ (1 \)

  • Each operation requires the selected index set different from each other

  • A request does not exceed \ (n + 1 \) views the program operation, there must be demonstrated

  • \ (1 \ n \ 10 ^ 3 \)

Practices: Construction

  • It can be obtained from the output format inspired(Excerpt from the official explanations)

  • We dare guess there is a exactly \ (n + 1 \) times of program operation

  • Each turn is determined considering the number of which is subtracted in operation \ (1 \)

  • Consider all \ (n + 1 \) operations into a set number, the same operation in each set index set, a start all operations are set within a

  • Required for all (n-\) \ after the number of processed, a respective set of all operations

  • So we can think of each finished with a number \ (a_i \) , to split at least one larger than \ (1 \) collection

  • Be split actually set ([1, n + 1] \) \ is selected in \ (a_i \) a Black remaining dyed white, then set for each of the original, while if included in this set of two kinds of color, color split it in accordance with the set

  • So we need to ensure that: If there is greater than \ (1 \) collection, then there must be a combination of both colors in one set

  • Taken lightly greater than \ (1 \) (whose size is set \ (S \) ) is set, this collection enumerate the number of elements blacked out (set to \ (J \) from \ (1 \) to \ (\ min (a_i,. 1-S) \) ), if the \ (a_i-j \ le n + 1-s \) is legitimate

  • Regardless of the selected can prove greater than \ (1 \) collection which, as long as the \ (a_i \ in [1, the n-] \) , legitimate program must exist

  • \ (O (the n-^ 2 \ the n-log) \) (if, like me, have to realize spicy chicken) or \ (O (n ^ 2) \)

Code

#include <bits/stdc++.h>

template <class T>
inline void read(T &res)
{
    res = 0; bool bo = 0; char c;
    while (((c = getchar()) < '0' || c > '9') && c != '-');
    if (c == '-') bo = 1; else res = c - 48;
    while ((c = getchar()) >= '0' && c <= '9')
        res = (res << 3) + (res << 1) + (c - 48);
    if (bo) res = ~res + 1;
}

const int N = 1005, rqy = 1e9 + 7;

int n, a[N], m, bel[N], sze[N], ans[N][N], T, has[N], tmp[N];

inline bool comp(int a, int b)
{
    return bel[a] < bel[b] || (bel[a] == bel[b] && ans[a][T] < ans[b][T]);
}

int main()
{
    read(n);
    for (int i = 1; i <= n; i++) read(a[i]);
    std::cout << n + 1 << std::endl;
    for (int i = 1; i <= n + 1; i++) bel[i] = 1;
    m = 1;
    for (int i = 1; i <= n; i++)
    {
        memset(sze, 0, sizeof(sze)); T = i;
        if (m == n + 1)
        {
            for (int j = 1; j <= a[i]; j++) ans[j][i] = 1;
            continue;
        }
        int p, cnt, tot = 0;
        for (int j = 1; j <= n + 1; j++) sze[bel[j]]++;
        for (int j = 1; j <= m; j++) if (sze[j] > 1) p = j;
        for (int j = 1; j < sze[p] && j <= a[i]; j++)
            if (a[i] - j <= n + 1 - sze[p])
                {cnt = j; break;}
        for (int j = 1; j <= n + 1; j++)
            if (bel[j] == p && (++tot) <= cnt) ans[j][i] = 1;
        tot = m = 0;
        for (int j = 1; j <= n + 1; j++)
            if (bel[j] != p && (++tot) <= a[i] - cnt) ans[j][i] = 1;
        for (int j = 1; j <= n + 1; j++) has[j] = j;
        std::sort(has + 1, has + n + 2, comp);
        for (int j = 1; j <= n + 1; j++)
        {
            int u = has[j], v = has[j - 1];
            if (j == 1 || bel[u] != bel[v] || ans[u][i] != ans[v][i]) m++;
            tmp[u] = m;
        }
        for (int j = 1; j <= n + 1; j++) bel[j] = tmp[j];
    }
    for (int i = 1; i <= n + 1; i++)
    {
        for (int j = 1; j <= n; j++) printf("%d", ans[i][j]);
        puts("");
    }
    return 0;
}

F

The meaning of problems

  • Given two sets \ (A \) and \ (B \)

  • \ (A \) can be expressed as \ (N_A \) intervals and set

  • \ (B \) can be expressed as \ (N_B \) intervals and set

  • Seeking \ (C = \ {x | x = a \ bigoplus b, a \ in A, b \ in B \} \) in all the sum of the numbers \ (998,244,353 \) result modulo

  • \ (\ bigoplus \) is the bitwise exclusive-OR operation

  • \ (. 1 \ Le N_A, N_B \ Le 100 \) , the endpoint is the interval \ (10 ^ {18} \) positive integer in the range

Practice: segment tree

  • Good question

  • The idea is obviously a set \ (A \) and (B \) \ were established as a range \ ([0,2 ^ {60} -1] \) of the segment tree, all of the sections is inserted into the tree line

  • Then a set of enumeration \ (A \) split the interval and a set of \ (B \) split the interval, readily available such interval may be represented as "front \ (K \) bits fixed, \ (60- K \) in the form of an arbitrary bit ", so that the exclusive oR of the two sections can be easily set with a same interval represented in the form of

  • In addition, these intervals necessarily correspond to a line segment tree nodes, if a node exists an ancestor appeared the impact of this node is not included in the answer

  • After it all the way in a certain interval (the line segment can be defined as tree sequence DFS) ordered such ancestors must appear in each interval prior to, can be achieved for each node determines whether to answer contributes to you can contribute to the range of all integers within the range and included answers

  • Set \ (L = 60 \) , then the complexity \ (O (n-2L ^ ^ 2 \ log (n-2L ^ ^ 2)) \) , due to the large constant, time and space through the segment tree are not

  • Consider how to optimize. We note that if a range can be expressed as "front \ (k \) bits fixed, \ (60-k \) position in any" form, and the other section can be expressed as "front \ (x \) bit fixed, after \ (60-x \) in the form of an arbitrary bit ", then the two intervals before the exclusive or collection interval \ (\ min (k, x ) \) bits is fixed, and only two, and the interval number front \ (\ min (k, x ) \) bits related

  • So consider \ (A \) a node on \ (P \) and (\ B) \ a node on \ (Q \) , provided \ (P \) of a depth less than \ (Q \) , can be shown if the \ (q \) becomes its father node, then \ (p \) and \ (q \) XOR collection is unchanged

  • Extraction interval while each segment tree traversal points up \ (4 \) a, so that two opening points dynamic segment tree, a layer is effective dots \ (O (n) \) level

  • Let us define for the set \ (A \) or \ (B \) , the input line segment tree given interval is split into sub-sections as black dots corresponding to the node, the remaining nodes of the tree segments white point

  • The properties of the resulting above, we can consider two segments enumeration tree same depth as a pair of points (the need to ensure at least a black dot), corresponding to the two points is calculated exclusive interval or intervals

  • Such readily available to give a final exclusive or collection is equivalent to the original

  • At this complexity is \ (O (n-2L ^ \ log (n-2L ^) \) , this problem can be

Code

#include <bits/stdc++.h>

template <class T>
inline void read(T &res)
{
    res = 0; bool bo = 0; char c;
    while (((c = getchar()) < '0' || c > '9') && c != '-');
    if (c == '-') bo = 1; else res = c - 48;
    while ((c = getchar()) >= '0' && c <= '9')
        res = (res << 3) + (res << 1) + (c - 48);
    if (bo) res = ~res + 1;
}

typedef long long ll;

const int N = 105, M = 5e4 + 5, L = 4e6 + 5, rqy = 998244353, I2 = 499122177;
const ll ET = (1ll << 60) - 1;

int n, na, nb, ans;

struct seg
{
    int rt, lc[M], rc[M], dep[M], ToT;
    bool mark[M];
    ll num[M];
    
    void orznc(int T, ll l, ll r, ll s, ll e, ll x, int &p)
    {
        if (e < l || s > r) return;
        if (!p) dep[p = ++ToT] = T, num[p] = x;
        if (s <= l && r <= e) return (void) (mark[p] = 1);
        ll mid = l + r >> 1;
        orznc(T - 1, l, mid, s, e, x, lc[p]);
        orznc(T - 1, mid + 1, r, s, e, x | (1ll << T - 1), rc[p]);
    }
} A, B;

struct elem
{
    int dep; ll num;
} a[L];

inline bool comp(elem a, elem b)
{
    return a.num < b.num || (a.num == b.num && a.dep > b.dep);
}

int main()
{
    ll l, r, lst = -1; int d;
    read(na);
    while (na--) read(l), read(r), A.orznc(60, 0, ET - 1, l, r, 0, A.rt);
    read(nb);
    while (nb--) read(l), read(r), B.orznc(60, 0, ET - 1, l, r, 0, B.rt);
    for (int p = 1; p <= A.ToT; p++)
        for (int q = 1; q <= B.ToT; q++)
            if (A.dep[p] == B.dep[q] && (A.mark[p] || B.mark[q]))
            {
                int T = A.dep[p];
                a[++n] = (elem) {T, A.num[p] ^ B.num[q]};
            }
    std::sort(a + 1, a + n + 1, comp);
    for (int i = 1; i <= n; i++)
    {
        if (lst != -1 && d >= a[i].dep && (lst >> d) == (a[i].num >> d))
            continue;
        d = a[i].dep; lst = a[i].num;
        ans = (lst % rqy * ((1ll << d) % rqy) + ans) % rqy;
        ans = (((1ll << d) % rqy) * (((1ll << d) - 1) % rqy)
            % rqy * I2 + ans) % rqy;
    }
    return std::cout << ans << std::endl, 0;
}

Guess you like

Origin www.cnblogs.com/xyz32768/p/11978470.html