2024年马蹄杯专科组第三场初赛 解题报告 | 珂学家


前言


题解

VP了这场比赛,整体还是偏简单,最难的题是数论相关,算一道思维题。

也看了赛时榜单,除了数论,大模拟和图论题也是拦路虎。



打工人

有趣的一道数学题,有点绕

很像数列和

∑ i = 1 i = n i = n ∗ ( n + 1 ) / 2 \sum_{i=1}^{i=n} i=n*(n+1)/2 i=1∑i=ni=n∗(n+1)/2

从公式结合时间复杂度,可以 n \sqrt n n 求解单次查询,时间复杂度 O ( q ∗ n ) O(q * \sqrt n) O(q∗n )是可行的。

对于区间 [ L , R ] [L, R] [L,R]问题,转化为函数差

f ( x ) = [ 1 , x ] 的累加和 f(x) = [1, x]的累加和 f(x)=[1,x]的累加和
g ( l , r ) = f ( r ) − f ( l − 1 ) g(l, r) = f(r) - f(l - 1) g(l,r)=f(r)−f(l−1)

关键在于如何求解这个函数 f ( x ) f(x) f(x)

cpp 复制代码
#include <bits/stdc++.h>

using namespace std;

using int64 = long long;

// 时间复杂度为O(\sqrt n)
int64 f(int v) {
    int64 r = 0;
    int acc = 0;
    for (int i = 1; acc <= v; i++) {
        r += (i * min(v - acc, i));
        acc += i;
    }
    return r;
}

int main() {
    int q;
    cin >> q;
    while (q-- > 0) {
        int l, r;
        cin >> l >> r;
        int64 r1 = f(l - 1);
        int64 r2 = f(r);
        cout << r2 - r1 << endl;
    }
    return 0;
}

当然这题是可以把单次查询优化为 O ( 1 ) O(1) O(1)的


P序列

其实是一道思维题。

可以从构造的角度,去解这道题,就会发现很容易。

因为其是一种山峰状的数组, 左侧非严格递增,右侧非严格递减。

对数进行分组,按值排序,然后放置于数组。

  1. 最大值先放于中间
  2. 按序依次放置其他数 v i v_i vi,若个数为 c n t v i cnt_{v_i} cntvi,其放置左右侧的方案数总共为 c n t v i + 1 cnt_{v_i} + 1 cntvi+1

根据乘法原理,最终的总方案数为

∏ ( c n t v i + 1 ) , v i ≠ v m a x {\prod (cnt_{v_i} + 1), v_i \ne v_{max}} ∏(cntvi+1),vi=vmax

cpp 复制代码
#include <bits/stdc++.h>

using namespace std;

using int64 = long long;

int64 mod = 998244353l;

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n;
    cin >> n;
    map<int, int> hp;

    int mz = -0x3f3f3f3f;
    for (int i = 0; i < n; i++) {
        int x;
        cin >> x;
        hp[x]++;
        mz = max(mz, x);
    }

    long long res = 1l;
    for (auto &[k, v] : hp) {
        if (k != mz) {
            res = res * (v + 1) % mod;
        }
    }
    cout << res << endl;

    return 0;
}

多项式输入

思路: 模拟

对于这类模拟题,最好的方式是拆分

多项式和拆分成

  • 符号
  • 系数
  • 指数

这三部分,然后分别处理,这样就会很清晰。

然后这边需要加入一个特例

就是全是 0 的情况 就是全是0的情况 就是全是0的情况

cpp 复制代码
#include<bits/stdc++.h> 

using namespace std;

int main( )
{
    int n;
    cin >> n;
    vector<int> vec(n + 1);
    for (int &x: vec) cin >> x;

    string s;
    bool first = true;

    for (int i = 0; i <= n; i++) {
        if (vec[i] == 0) continue;
        // 1. 处理符号
        if (first) {
            s.append(vec[i] > 0 ? "": "-");
        } else {
            s.append(vec[i] > 0 ? "+" : "-");
        }

        // 2. 系数部分
        int x = abs(vec[i]);
        if (i != n && x > 1) {
            s.append(to_string(x));
        } else if (i == n) {
            s.append(to_string(x));
        }
        // 3. 指数部分
        if (i < n - 1) {
            s.append("x^");
            s.append(to_string(n - i));
        } else if (i == n - 1) {
            s.append("x");
        } 
        first = false;
    }
    // 特别处理0这个特例
    if (s.length() == 0) {
        s = "0";
    }

    cout << s << endl;

    return 0;
}

写在最后

相关推荐
shinelord明几秒前
【再谈设计模式】享元模式~对象共享的优化妙手
开发语言·数据结构·算法·设计模式·软件工程
新手小袁_J6 分钟前
JDK11下载安装和配置超详细过程
java·spring cloud·jdk·maven·mybatis·jdk11
呆呆小雅6 分钟前
C#关键字volatile
java·redis·c#
დ旧言~7 分钟前
专题八:背包问题
算法·leetcode·动态规划·推荐算法
Monly217 分钟前
Java(若依):修改Tomcat的版本
java·开发语言·tomcat
boligongzhu8 分钟前
DALSA工业相机SDK二次开发(图像采集及保存)C#版
开发语言·c#·dalsa
Eric.Lee20218 分钟前
moviepy将图片序列制作成视频并加载字幕 - python 实现
开发语言·python·音视频·moviepy·字幕视频合成·图像制作为视频
Ttang239 分钟前
Tomcat原理(6)——tomcat完整实现
java·tomcat
7yewh10 分钟前
嵌入式Linux QT+OpenCV基于人脸识别的考勤系统 项目
linux·开发语言·arm开发·驱动开发·qt·opencv·嵌入式linux
钱多多_qdd20 分钟前
spring cache源码解析(四)——从@EnableCaching开始来阅读源码
java·spring boot·spring