其他分享
首页 > 其他分享> > [题解][Codeforces]Codeforces Round #602 (Div. 1) 简要题解

[题解][Codeforces]Codeforces Round #602 (Div. 1) 简要题解

作者:互联网

A

题意

做法:构造

代码

#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

题意

做法:贪心 + 树状数组上二分

代码 (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

题意

做法:二分 + 贪心 + 二维前缀和

代码

#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

题意

做法:组合数学

代码

#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

题意

做法:构造

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

题意

做法:线段树

代码

#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;
}

标签:le,602,int,题解,Codeforces,区间,&&,res,集合
来源: https://www.cnblogs.com/xyz32768/p/11978470.html