ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

多校冲刺 NOIP 20211106 模拟 (24)

2021-11-15 06:31:18  阅读:142  来源: 互联网

标签:24 20211106 ch const NOIP int mid lsh long


T1

第一类斯特林数裸题

T2

一对相同的字符会产生一次重复的贡献,分计算26种字符的出现次数\(cnt_i\),然后总和减去\(\frac{cnt_i*(cnt_i-1)}{2}\)

T4

不难得出一个人只会向左一直走然后右转,或向右一直走然后左转,且不会经过旁边的人的初始位置

于是可以dp,\(f_{i,j}\)表示第 i 个人终止在第 j 个点,前 i 个人的最短时间

转移就考虑枚举第 i-1 个人的终止位置,和第 i 个人的终止位置,计算第 i 个人移动的时间

考虑到整个dp实际只会有\(O(n)\)的合法状态,可以考虑将第二维在unordered_map上进行

空间复杂度\(O(n)\),时间复杂度未知

代码

T1

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int mod = 998244353;
const int N = 3e3 + 11;
int n, k;
int f[N][N];
inline void md(int& x) {
    if (x >= mod)
        x -= mod;
    return;
}
inline int read() {
    int s = 0;
    char ch = getchar();
    while (ch > '9' || ch < '0') ch = getchar();
    while (ch >= '0' && ch <= '9') s = (s << 1) + (s << 3) + (ch ^ 48), ch = getchar();
    return s;
}
signed main() {
    FILE* x = freopen("broken.in", "r", stdin);
    x = freopen("broken.out", "w", stdout);
    n = read();
    k = read();
    f[0][0] = 1;
    int ans = 0;
    for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= k; ++j) md(f[i][j] += f[i - 1][j - 1] + f[i - 1][j] * (i - 1) % mod);
    for (int i = 1; i <= k; ++i) md(ans += f[n][i]);
    cout << ans << endl;
    return 0;
}

T2

#include <bits/stdc++.h>
using namespace std;
#define ull unsigned long long
const ull p = 131;
const int N = 3e6 + 11;
char tx[N];
int n;
ull cnt[N];
ull mi[N];
int main() {
    FILE* h = freopen("turn.in", "r", stdin);
    h = freopen("turn.out", "w", stdout);
    cin >> (tx + 1);
    n = strlen(tx + 1);
    for (int i = 1; i <= n; ++i) ++cnt[tx[i] - 'a' + 1];
    ull sl = 0;
    for (int i = 1; i <= 26; ++i) sl += cnt[i] * (cnt[i] - 1) / 2;
    cout << 1ll * n * (n - 1) / 2 - sl + 1 << endl;
    return 0;
}

T4

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 3e6 + 11;
const int inf = 1e18;
int n, m;
int x[N], y[N];
int lsh[N], num;
unordered_map<int, int> f[N];
inline int max_(int a, int b) { return a > b ? a : b; }
inline int min_(int a, int b) { return a > b ? b : a; }
inline int calc(int l, int mid, int r) {
    return l = lsh[l], r = lsh[r], mid = lsh[mid], 2 * min_(mid - l, r - mid) + max_(mid - l, r - mid);
}
inline int read() {
    int s = 0;
    char ch = getchar();
    while (ch > '9' || ch < '0') ch = getchar();
    while (ch >= '0' && ch <= '9') s = (s << 1) + (s << 3) + (ch ^ 48), ch = getchar();
    return s;
}
void lsh_() {
    sort(lsh + 1, lsh + num + 1);
    int h = unique(lsh + 1, lsh + num + 1) - lsh;
    for (int i = 1; i <= n; ++i) x[i] = lower_bound(lsh + 1, lsh + h, x[i]) - lsh;
    for (int i = 1; i <= m; ++i) y[i] = lower_bound(lsh + 1, lsh + h, y[i]) - lsh;
    return;
}
signed main() {
    FILE* p = freopen("duplication.in", "r", stdin);
    p = freopen("duplication.out", "w", stdout);
    n = read(), m = read();
    for (int i = 1; i <= n; ++i) lsh[++num] = x[i] = read();
    for (int i = 1; i <= m; ++i) lsh[++num] = y[i] = read();
    sort(x + 1, x + n + 1);
    sort(y + 1, y + m + 1);
    lsh_();
    if (n == 1) {
        if (lsh[y[1]] > lsh[x[1]])
            cout << lsh[y[m]] - lsh[x[1]] << endl;
        else if (lsh[y[m]] < lsh[x[1]])
            cout << lsh[x[1]] - lsh[y[1]] << endl;
        else
            cout << calc(y[1], x[1], y[m]) << endl;
        return 0;
    }
    for (int i = x[1]; i < x[2]; ++i) {
        if (lsh[y[1]] < lsh[x[1]])
            f[1][i] = calc(y[1], x[1], i);
        else
            f[1][i] = lsh[i] - lsh[x[1]];
    }
    for (int i = 2; i < n; ++i) {
        for (int k = x[i]; k <= x[i + 1] - 1; ++k) f[i][k] = inf;
        for (int j = x[i - 1] + 1; j <= x[i]; ++j)
            for (int k = x[i]; k <= x[i + 1] - 1; ++k)
                f[i][k] = min_(f[i][k], max_(f[i - 1][j - 1], calc(j, x[i], k)));
    }
    if (lsh[y[m]] > lsh[x[n]])
        f[n][y[m]] = inf;
    else
        f[n][x[n]] = inf;
    for (int i = x[n - 1] + 1; i <= x[n]; ++i) {
        if (lsh[y[m]] > lsh[x[n]])
            f[n][y[m]] = min_(f[n][y[m]], max_(f[n - 1][i - 1], calc(i, x[n], y[m])));
        else
            f[n][x[n]] = min_(f[n][x[n]], max_(f[n - 1][i - 1], calc(i, x[n], x[n])));
    }
    if (lsh[y[m]] > lsh[x[n]])
        cout << f[n][y[m]] << endl;
    else
        cout << f[n][x[n]] << endl;
    return 0;
}

标签:24,20211106,ch,const,NOIP,int,mid,lsh,long
来源: https://www.cnblogs.com/sitiy/p/15554298.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有