C. Unstable Elements

题目链接

一些废话

我知道这道题不难,但不知道为什么,就是写了很多遍,刚开始的时候题目读的是对的,但写着写着就忘了题目原意了,搞笑,然后之后又写了两版,都是将 k 个数字记成总和是 kk 了,之后又看了一遍题目,再改了几下,终于对了

题意

给出一个数组 aa 和一个整数 kk,每次可以执行以下操作:

  • 标记该数组中每个与其左邻不相等的数字,如所有满足 aiai+1a_i \neq a_{i +1}ii
  • 要么统一删除满足以上要求的 aia_i,要么统一复制满足以上要求的 aia_i

保证输入规则:a1a2 . . .an,aina_1 \leq a_2 \ . \ . \ . \leq a_n , \quad a_i \leq n

思路

发现,每次整体删除数字,直到遇到一组出现次数相同的被删完,然后再复制回去才有可能出现新的方案,所以我们先记录每个数字出现的次数,然后保存同一种出现次数对应的数字的个数,这个是为了反推回去,然后我们从 1 开始递增判断出现次数大于等于 ii 的种数。唉,我没招了,我真没招了,我不知道怎么讲才能讲得清楚,所以最后录了个视频,我可是专门为了你,发布了哔站第一个视频啊(呃,其实是为了视频不占内存)

【C. Unstable Elements-哔哩哔哩】

代码

#include <bits/stdc++.h>
using namespace std;
#define lowbit(x) (x & (-x))
#define endl '\n'
typedef long long LL;
#define PLL pair<LL, LL>
const LL MOD = 998244353;
const LL MAX = 1e6 + 100;
const LL INF = 0x3f3f3f3f3f3f3f;

void solve() {
    int n, k;
    cin >> n >> k;

    int sm = 0;
    vector<int> a(n + 1, 0), b(n + 1, 0), cnt(n + 1, 0), cnt1(n+ 1, 0);
    for (int i = 1; i <= n; ++i) {
        int x;
        cin >> x;
        a[x]++;
        sm++;
    }

    for (int i = 1; i <= n; ++i) {
        if (a[i]) {
            cnt[a[i]]++;
        }
    }

    vector<int> sf(n + 2, 0);
    for (int i = n; i >= 1; --i) {
        sf[i] = sf[i + 1] + cnt[i];
    }

    set<int> res;
    for (int i = 1; i <= n && sm >= 0; ++i) {
        if (sf[i] != 0 && k >= sm && (k - sm) % sf[i] == 0) {
            res.insert(sf[i]);
        }
        sm -= sf[i];
    }

    cout << res.size() << endl;
}

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);

    LL T;
    cin >> T;
    while (T--) {
        solve();
    }
    return 0;
}



「一定没有问题的!」
— 魔卡少女樱

Leave a Comment

您的邮箱地址不会被公开。 必填项已用 * 标注