//https://img2018.cnblogs.com/blog/1646268/201908/1646268-20190806114008215-138720377.jpg

2023.10.27牛客

2023.10.27 牛客解题报告

T1

打一个 \(100\) 以内的表,可以发现直接输出 \(n + 1\) 就是答案。

/*
 * @Author: Aisaka_Taiga
 * @Date: 2023-10-27 19:04:33
 * @LastEditTime: 2023-10-27 19:11:14
 * @LastEditors: Aisaka_Taiga
 * @FilePath: \Desktop\T1.cpp
 * The heart is higher than the sky, and life is thinner than paper.
 */
#include <bits/stdc++.h>

#define int long long
#define P 998244353
#define N 1001000

using namespace std;

inline int read()
{
    int x = 0, f = 1;
    char c = getchar();
    while(c < '0' || c > '9'){if(c == '-') f = -1; c = getchar();}
    while(c <= '9' && c >= '0') x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
    return x * f;
}

int n, f[N];

inline int F(int x)
{
    if(f[x]) return f[x];
    return f[x] = (2 * F(x - 1) - F(x - 2)) % P;
}

signed main()
{
    n = read();
    // f[0] = 1, f[1] = 2;
    // for(int i = 1; i <= n; i ++)
        // cout << " I : " << F(i) << endl;
    // for(int i = 1; i <= n; i ++)
        // cout << "SDA: " << f[i] / f[i - 1] << endl;
    cout << n + 1 << endl;
    return 0;
}

T2

\(a_{i}\) 为班级 \(i\) 的人数。

答案即为 \(max(max\{a[i]\}, n-k)\)

\(max\{a[i]\}\) 表示 \(a[i]\) 中的最大值。

/*
 * @Author: Aisaka_Taiga
 * @Date: 2023-10-27 19:20:09
 * @LastEditTime: 2023-10-27 19:21:30
 * @LastEditors: Aisaka_Taiga
 * @FilePath: \Desktop\T2.cpp
 * The heart is higher than the sky, and life is thinner than paper.
 */
#include <bits/stdc++.h>

#define int long long
#define N 1000100

using namespace std;

inline int read()
{
    int x = 0, f = 1;
    char c = getchar();
    while(c < '0' || c > '9'){if(c == '-') f = -1; c = getchar();}
    while(c <= '9' && c >= '0') x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
    return x * f;
}

int n, m, k;
struct node{int id, v;}e[N];

inline int cmp(node a, node b){return a.v > b.v;}

signed main()
{
    n = read(), m = read(), k = read();
    for(int i = 1; i <= n; i ++) e[read()].v ++;
    for(int i = 1; i <= m; i ++) e[i].id = i;
    sort(e + 1, e + m + 1, cmp);
    cout << min(e[1].v, n - k) << endl;
    return 0;
}

T3

直接枚举每一个答案人数 \(x\),然后暴力判断将所有的班级改为不大于 \(x\) 的花费,看是不是大于 \(k\) 来判断是不是合法,直到遇见合法的为止。

/*
 * @Author: Aisaka_Taiga
 * @Date: 2023-10-27 19:43:36
 * @LastEditTime: 2023-10-27 20:05:14
 * @LastEditors: Aisaka_Taiga
 * @FilePath: \Desktop\T3_T4.cpp
 * The heart is higher than the sky, and life is thinner than paper.
 */
#include <bits/stdc++.h>

#define int long long
#define N 1000100
 
using namespace std;

inline int read()
{
    int x = 0, f = 1;
    char c = getchar();
    while(c < '0' || c > '9'){if(c == '-') f = -1; c = getchar();}
    while(c <= '9' && c >= '0') x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
    return x * f;
}

int n, m, k, ans[N];
struct node{int id, v;}e[N];

inline int cmp(node a, node b){return a.v > b.v;}

signed main()
{
    n = read(), m = read(), k = read();
    for(int i = 1; i <= n; i ++) e[read()].v ++;
    for(int i = 1; i <= m; i ++) e[i].id = i;
    sort(e + 1, e + m + 1, cmp);
    e[m + 1].v = -1e9;
    for(int i = 1; i <= m; i ++)
    {
        int t = 0, kk = 0;
        if(n - e[i].v < k){ans[e[i].id] = -1; continue;}
        for(int j = e[1].v; j >= 0; j --)
        {
            if(j == 0) {ans[e[i].id] = 0; break;}
            while(e[t + 1].v >= j) t ++;
            if(e[i].v >= j) kk --;
            kk += t;
            if(kk > k){ans[e[i].id] = j; break;}
        }
    }
    for(int i = 1; i <= m; i ++)
        cout << ans[i] << " ";
    return 0;
}

T4

数据加强版T3

考虑维护两个前缀和,\(sum1\) 表示当前人数有多少班级有贡献,\(sum2\) 表示人数为 \(i\sim m\) 的班的人数和。

接下来二分我们的答案人数。

考虑如何计算这个走的人数,设当前二分到的人数为 \(x\), 当前是 \(i\) 班拖堂,那么答案就是 \(sum2[x] - sum1[x]\)

如果要是 \(a[i]\ge x\),也就是当前班的人数对 \(sum2\) 有贡献了,要减去 \(a[i]\),同时 \(sum1\) 里当前点是对 \(x\) 个有贡献,所以是:

\[sum2[x] - [a[i]\ge x] \times a[i] - (sum1[x] - [a[i] >= x]) \times x \]

其中中括号表示如果中括号里的成立则值为 \(1\),反之为 \(0\)

/*
 * @Author: Aisaka_Taiga
 * @Date: 2023-10-27 21:13:38
 * @LastEditTime: 2023-10-27 22:11:58
 * @LastEditors: Aisaka_Taiga
 * @FilePath: \Desktop\T4std.cpp
 * The heart is higher than the sky, and life is thinner than paper.
 */
#include <bits/stdc++.h>

#define int long long
#define N 1000100

using namespace std;

inline int read()
{
    int x = 0, f = 1;
    char c = getchar();
    while(c < '0' || c > '9'){if(c == '-') f = -1; c = getchar();}
    while(c <= '9' && c >= '0') x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
    return x * f;
}

int n, m, k, a[N], sum1[N], sum2[N];

inline int check(int x, int i){return (sum2[x] - (a[i] >= x) * a[i]) - (sum1[x] - (a[i] >= x)) * x;}

signed main()
{
    n = read(), m = read(), k = read();
    for(int i = 1; i <= n; i ++) a[read()] ++;
    for(int i = 1; i <= m; i ++) sum1[a[i]] ++, sum2[a[i]] += a[i];
    for(int i = n - 1; i >= 0; i --) sum1[i] += sum1[i + 1], sum2[i] += sum2[i + 1];
    for(int i = 1; i <= m; i ++)
    {
        if(n - a[i] < k){cout << "-1 "; continue;}
        int l = 0, r = n;
        while(l < r)
        {
            int mid = l + r >> 1;
            if(check(mid, i) <= k) r = mid;
            else l = mid + 1;
        }
        cout << l << " ";
    }
    cout << endl;
    for(int i = 0; i <= n; i ++)
        cout << sum1[i] << " ";
    return 0;
}
posted @ 2023-10-27 22:28  北烛青澜  阅读(1)  评论(0编辑  收藏  举报