• YAOI Summer Round #4 (Div.2) 题解


    前言

    个人认为比普及组难度要略低,但实际测试结果极不理想。

    题解

    以下是这场比赛的各题题解。

    #5101. YAOI Summer Round #4 (Div 2) A. 子串之美

    得分率正常。

    对于 (20\%) 的数据,考虑直接枚举子串,再加上一些剪枝,考场上果然也没人写。

    对于 (50\%) 的数据,考虑用 KMP 算法去统计每个子串,可以做到 (O(nlog n)) 的复杂度。

    对于另外 (10\%) 的数据,显然 a 是出现次数最多的非空子串,出现次数为 (n)

    对于 (100\%) 的数据,显然出现次数最多的非空子串长度为 (1),于是用桶存一下每个字母的出现次数即可。

    #include <bits/stdc++.h>
    #define Re register
    using namespace std;
    
    int n, d[31], ans;
    char s[10000005];
    
    int main() {
        scanf("%d", &n);
        scanf("%s", s + 1);
        for (Re int i = 1; i <= n; i++) {
            d[s[i] - 'a']++;
        }
        for (Re int i = 0; i < 26; i++) {
            ans = max(ans, d[i]);
        }
        printf("%d", ans);
        return 0;
    }
    

    #5102. YAOI Summer Round #4 (Div 2) B. 集合与映射

    得分率略低于预期。

    对于 (30\%) 的数据,分别求出 (A,B,C) 即可,复杂度为 (O(n^2))

    对于另外 (20\%) 的数据,有 (10\%) 为单调递增,有 (10\%) 为单调递减。

    单调递增的那部分,显然可以得到答案为 (0)

    单调递减的那部分,如果有用心去算的话,很容易发现是序列的逆序对数。

    对于 (100\%) 的数据,我们通过大力分类讨论(大体上分出了 (7) 类,读者可以尝试自行证明),可以证明就是序列中逆序对的数量。

    故可以在 (O(nlog n)) 的复杂度内完成本题。

    #include <bits/stdc++.h>
    #define Re register
    using namespace std;
    
    typedef long long ll;
    const int N = 1000005;
    int n, f[N];
    ll c[N], ans;
    
    inline int lb(int x) { return x & -x; }
    
    inline void add(int p) {
        for (; p <= n; p += lb(p)) c[p]++;
    }
    
    inline ll qry(int p) {
        ll res = 0;
        for (; p; p -= lb(p)) res += c[p];
        return res;
    }
    
    int main() {
        scanf("%d", &n);
        for (Re int i = 1; i <= n; i++) {
            scanf("%d", &f[i]);
        }
        for (Re int i = 1; i <= n; i++) {
            add(f[i]);
            ans += i - qry(f[i]);
        }
        printf("%lld", ans);
        return 0;
    }
    

    #5103. YAOI Summer Round #4 (Div 2) C. 取物游戏

    得分率远低于预期。

    对于 (20\%) 的数据,直接模拟题意爆搜即可。

    对于 (50\%) 的数据,是写正解做法被卡时间或空间所得到的分。

    对于 (100\%) 的数据,考虑设 (dp[i][j][k][0/1]) 表示在点 ((i,j)) 处,差值为 (k),这一步是 Alice 取还是 Bob 取的方案数。(如果状态不小心多设了一维,就变成 (50\%) 的那一档)

    转移很容易想到,具体见代码。

    时间复杂度为 (O(nmk)),空间复杂度为 (O(nmk))

    #include <bits/stdc++.h>
    #define Re register
    using namespace std;
    
    const int N = 605, K = 35;
    const int mod = 1000000007;
    
    int n, m, k, ans;
    int a[N][N];
    int dp[N][N][K][2];
    
    int main() {
        scanf("%d%d%d", &n, &m, &k);
        for (Re int i = 1; i <= n; i++) {
            for (Re int j = 1; j <= m; j++) {
                scanf("%d", &a[i][j]);
                a[i][j] %= k;
                dp[i][j][a[i][j]][1] = 1;
            }
        }
        for (Re int i = 1; i <= n; i++) {
            for (Re int j = 1; j <= m; j++) {
                for (Re int s = k; s >= 0; s--) {
                    (dp[i][j][s][1] += dp[i - 1][j][(s + k - a[i][j]) % k][0]) %= mod;
                    (dp[i][j][s][1] += dp[i][j - 1][(s + k - a[i][j]) % k][0]) %= mod;
                    (dp[i][j][s][0] += dp[i - 1][j][(s + a[i][j]) % k][1]) %= mod;
                    (dp[i][j][s][0] += dp[i][j - 1][(s + a[i][j]) % k][1]) %= mod;
                }
            }
        }
        for (Re int i = 1; i <= n; i++) {
            for (Re int j = 1; j <= m; j++) {
                ans = (ans + dp[i][j][0][0]) % mod;
            }
        }
        printf("%d", ans);
        return 0;
    }
    

    #5104. YAOI Summer Round #4 (Div 2) D. 矩阵

    得分率远低于预期。

    首先,我们会意识到令所有的 (max(x,y)modmin(x,y)=1) 不劣,下面再进行讨论。

    对于 (20\%) 的数据,通过计算器容易构造出一组解。(从左到右从上到下构造即可)

    对于 (40\%) 的数据,考虑像国际象棋那样黑白染色,染黑色的取互不相同的质数,染白色的取周围 (4) 个黑色格子中数的乘积即可。

    对于 (100\%) 的数据,实际上与 (40\%) 类似,只需要把质数的相对位置进行微调,让大的两个和小的两个配在一起就好了。

    复杂度 (O(n^2))

    #include <bits/stdc++.h>
    #define Re register
    using namespace std;
    
    typedef long long ll;
    
    const int N = 505, TOT = 10000005;
    
    int n, tot, p[TOT];
    bool vis[TOT];
    ll a[N][N];
    
    inline void prework(int mxn) {
        vis[1] = 1;
        for (Re int i = 2; i <= mxn; i++) {
            if (!vis[i])
                p[++tot] = i;
            for (Re int j = 1; j <= tot && i * p[j] <= mxn; j++) {
                vis[i * p[j]] = 1;
                if (i % p[j] == 0)
                    break;
            }
        }
    }
    
    inline ll gcd(ll x, ll y) { return y == 0 ? x : gcd(y, x % y); }
    
    inline ll lcm(ll x, ll y) {
        if (x == 0 || y == 0)
            return x + y;
        return 1ll * x / gcd(x, y) * y;
    }
    
    int main() {
        prework(10000000);
        scanf("%d", &n);
        if (n == 2) {
            printf("4 7
    ");
            printf("23 10
    ");
            return 0;
        }
        for (Re int i = 1; i <= n; i++) {
            for (Re int j = 1; j <= n; j++) {
                if ((i + j) % 2 == 0) {
                    a[i][j] = 1ll * p[(i + j) / 2] * p[n + (n + 1) / 2 + (i - j) / 2];
                }
            }
        }
        for (Re int i = 1; i <= n; i++) {
            for (Re int j = 1; j <= n; j++) {
                if ((i + j) % 2 == 1) {
                    a[i][j] = lcm(lcm(a[i - 1][j], a[i][j - 1]), lcm(a[i + 1][j], a[i][j + 1])) + 1;
                }
            }
        }
        for (Re int i = 1; i <= n; i++) {
            for (Re int j = 1; j <= n; j++) {
                printf("%lld ", a[i][j]);
            }
            puts("");
        }
        return 0;
    }
    
  • 相关阅读:
    调整心态,夯实基础
    js实现轮播图动画(更新"旋转木马")
    封装简单动画函数-由简到完善
    纯Css绘制三角形箭头三种方法
    JS实现图片''推拉门''效果
    一个基于 canvas 的画板
    Python 控制台进度条的实现
    Flask博客开发——Tinymce编辑器
    Flask博客开发——登录验证码
    用于水和水蒸汽物性计算的Python模块——iapws
  • 原文地址:https://www.cnblogs.com/kebingyi/p/15167399.html
Copyright © 2020-2023  润新知