• 分享
  • 分治第7题 CF1956D Nene and the Mex Operator

  • @ 2025-6-4 21:09:51

https://www.luogu.com.cn/problem/CF1956D

#include <bits/stdc++.h>
using namespace std;
const int maxn = 25;

int n, a[maxn];
vector<pair<int, int>> ans;

void test() {
    putchar('\t');
    for (int i = 1; i <= n; i++)
        printf("%d,", a[i]);
    puts(" !");
}

int mex(int l, int r) {
    set<int> st;
    for (int i = l; i <= r; i++)
        st.insert(a[i]);
    for (int i = 0; ; i++)
        if (!st.count(i))
            return i;
}

// 判断 a[l..r] 全是 0
bool check(int l, int r) {
    for (int i = l; i <= r; i++)
        if (a[i])
            return false;
    return true;
}

// 对 a[l..r] 进行一次操作
void f(int l, int r) {
//    printf("%d %d\n", l, r);
    ans.push_back({l, r});
    int x = mex(l, r);
    for (int i = l; i <= r; i++)
        a[i] = x;
//    test();
}

// 将 a[l..r] 清空为 0
void clean(int l, int r) {
    while (!check(l, r)) {
        f(l, r);
    }
}

void op2(int l, int r, int x);

// 将 a[l..r] 变成 x, 0, 0, .., 0
void op1(int l, int r, int x) {
    if (x == 0) {
        clean(l, r);
        return;
    }
    if (x == 1) {
        clean(l, r);
        f(l, r);
        if (l < r) clean(l+1, r);
        return;
    }
    op2(l, r, x-1);
    f(l, l+x-1);
    clean(l+1, r);
}

// 将 a[l..r] 变成 x, x-1, x-2, .., 2, 1, 0, 0, .., 0
void op2(int l, int r, int x) {
    if (x == 0) {
        clean(l, r);
        return;
    }
    if (x == 1) {
        clean(l, r);
        f(l, r);
        if (l < r) clean(l+1, r);
        return;
    }
    op1(l, r, x);
    op2(l+1, r, x-1);
}

int sum[maxn], tar[maxn][maxn], val[maxn][maxn];
bool vis[maxn][maxn];

int dfs1(int l, int r) {
    if (l > r) return 0;
    if (vis[l][r]) return val[l][r];
    vis[l][r] = true;
    val[l][r] = sum[r] - sum[l-1];
    tar[l][r] = -1;
    int tmp = (r - l + 1) * (r - l + 1);
    if (tmp > val[l][r])
        val[l][r] = tmp, tar[l][r] = r;
    for (int i = l; i < r; i++) {
        tmp = dfs1(l, i) + dfs1(i+1, r);
        if (tmp > val[l][r])
            val[l][r] = tmp, tar[l][r] = i;
    }
    return val[l][r];
}

void dfs2(int l, int r) {
    if (tar[l][r] == -1)
        return;
    if (tar[l][r] == r) {
        op2(l, r, r-l);
        f(l, r);
        return;
    }
    dfs2(l, tar[l][r]);
    dfs2(tar[l][r]+1, r);
}

int main() {
    scanf("%d", &n);
    for (int i = 1; i <= n; i++)
        scanf("%d", a+i), sum[i] = sum[i-1] + a[i];
    dfs1(1, n);
    dfs2(1, n);
    printf("%d %d\n", dfs1(1, n), (int)ans.size());
    for (auto pi : ans)
        printf("%d %d\n", pi.first, pi.second);
    return 0;
}

0 条评论

目前还没有评论...