题解 | あなたの蛙が帰っています

あなたの蛙が帰っています

https://www.nowcoder.com/practice/44a2fc12a92a4eccb13a78eabfb67063

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

const ll MOD = 998244353;  // 模数

// 快速幂算法 
// 功能:计算 a^b % mod
// 原理:利用二进制拆分,将指数b表示为二进制形式
// 例如:3^13 = 3^(1101₂) = 3^8 × 3^4 × 3^1
ll power(ll a, ll b, ll mod) {
    ll result = 1;      // 初始结果为1
    a %= mod;           // 先对a取模,防止溢出

    while (b > 0) {     // 当指数大于0时继续
        // 检查b的最低位是否为1
        if (b & 1) {    // 相当于 if (b % 2 == 1)
            // 如果当前位是1,将对应的a^(2^i)乘入结果
            result = result * a % mod;
        }

        // a自乘,从a^1变成a^2, a^4, a^8, ...
        a = a * a % mod;

        // b右移一位,相当于b除以2
        b >>= 1;        // 相当于 b /= 2
    }

    return result;
}

// 模逆元 
// 功能:计算 a 在模 mod 下的乘法逆元
// 定义:若 a × x ≡ 1 (mod p),则称x为a的逆元,记作a^(-1)
// 原理:根据费马小定理,当p为质数时,a^(p-1) ≡ 1 (mod p)
//      因此 a^(p-2) × a ≡ 1 (mod p)
//      所以 a^(-1) = a^(p-2) mod p
ll inv(ll a, ll mod) {
    // 利用费马小定理:a^(-1) = a^(mod-2) mod mod
    return power(a, mod - 2, mod);
}

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

    int T;
    cin >> T; 

    // 卡特兰数C(n)表示:n个元素的合法出栈序列数
    // 卡特兰数:C(n) = (2n)! / ((n+1)! × n!)
    int maxN = 100005;  // 最大n值(根据题目数据范围1≤𝑁≤10^5)
    vector<ll> catalan(maxN);

    // 初始条件
    catalan[0] = 1;  // C(0) = 1
    catalan[1] = 1;  // C(1) = 1

    // 递推计算卡特兰数 
    // 递推公式:C(n) = C(n-1) × 2(2n-1) / (n+1)
    // 推导过程:
    // C(n) = (2n)! / ((n+1)! × n!)
    // C(n-1) = (2n-2)! / (n! × (n-1)!)
    // C(n) / C(n-1) = [(2n)! / ((n+1)! × n!)] / [(2n-2)! / (n! × (n-1)!)]
    //                = (2n)! × n! × (n-1)! / ((n+1)! × n! × (2n-2)!)
    //                = (2n)(2n-1)(2n-2)! / ((n+1) × n × (n-1)! × n!)
    //                = (2n)(2n-1) / ((n+1) × n)
    //                = 2(2n-1) / (n+1)
    // 因此:C(n) = C(n-1) × 2(2n-1) / (n+1)

    for (int i = 2; i < maxN; i++) {
        // 计算 C(i) = C(i-1) × 2(2i-1) / (i+1)

        // 步骤1:C(i-1) × 2(2i-1)
        catalan[i] = catalan[i - 1] * (4 * i - 2) % MOD;

        // 步骤2:除以 (i+1)
        // 在模运算下,除法 = 乘以逆元
        // a / b ≡ a × b^(-1) (mod p)
        catalan[i] = catalan[i] * inv(i + 1, MOD) % MOD;
    }

    // 处理每个测试用例 
    for (int caseNum = 1; caseNum <= T; caseNum++) {
        int n;
        cin >> n;

        ll result;

        // 特判:n=1时,A1不能第一个出栈,无解
        if (n == 1) {
            result = 0;
        }
        else {
            // 答案 = C(n) - C(n-1)
            //  C(n):所有合法的出栈序列数
            //  C(n-1):A1第一个出栈的序列数(相当于剩余n-1个元素的标准问题)
            //  C(n) - C(n-1):A1不第一个出栈的序列数

            result = (catalan[n] - catalan[n - 1] + MOD) % MOD;

            // 加MOD是为了防止结果为负数
            // 在模运算下,(a - b) % MOD 可能是负数
            // 正确做法:(a - b + MOD) % MOD
        }

        cout << "Case #" << caseNum << ": " << result << '\n';
    }

    return 0;
}

全部评论

相关推荐

04-12 21:52
南开大学 Java
鼠鼠有点摆,去年边学着没敢投简历,没实习。从1月到现在总共面了五次,四次字节的日常(HR打电话约面试才敢去的),然后一次腾讯的暑期,都是一面挂,其他则是没给面。暑期的岗,4.2才开始海投,前面想着等字节第四次一面后再投,结果挂,而且感觉投晚了。字节投了11个,9个简历挂,剩下2个没动静。阿里全都简历挂,剩下的在&quot;投递简历&quot;。腾讯给了一次面。然后其他大中厂、手机厂什么的都是做完测评or笔试就没下文,打开几个看也是终止流程,感觉剩下的也应该是简历挂了。感觉是简历的原因?项目部分,几次面试,感觉面试官主要就拷问过秒杀这一个点。自己说的时候会尝试把sse那条说成亮点,但除了腾讯面试官问过一下这整个点在业务方面对用户有什么用之类的问题外,其他最多只是问一下sse八股...感觉也许不是很让面试官感兴趣。这个短链接也是无人问津,就被问过一回雪花算法的设计。也许我该拿点评改改,然后再在网上找一个什么项目,凑两个,而不是用自己现在这两个项目?或者是点评改改放前面,然后原本第一个项目,把秒杀抽掉,剩下的想办法从网上火的RAG项目里移植点亮点,或者直接就用网上的RAG项目?感觉我主要还是偏向后端开发,但是感觉如果除开点评,再拿一个项目,想不到有什么自己能掌控且跟点评不重的。然后鼠鼠之前主要的问题是担心面试让打开项目演示,然后就一直花时间在用AI整第一个项目,第二个项目都没时间整,第四次面试之前还因为太害怕被认为不熟悉项目,跟AI一起把简历的说辞做了大幅度弱化,然后暑期都是拿弱化后的简历投的,感觉是不是看上去太没有吸引力就直接给简历挂了。(图1是弱化后的,图2是弱化前的,但之前3月初投了几家好像也是简历挂。)而且因为3月花了很多时间整在跟AI整代码,导致八股和算法都没怎么看,算法之前有跟灵神题单刷一些,还算入门,但是八股只看了一些基本的,可能面试的时候只答得上来60-70%,而且表述有些混乱,都是想到哪说到哪;前面几回面试基本上都有大板块的基础八股没答出来,比如RedisZ&nbsp;Set数据结构,MQ延时消息、可靠性保证,JVM内存分配的过程、GC&nbsp;roots,JUC锁,设计模式。现在有点不知道该怎么办。求大佬们给点简历修改建议或者面试准备建议,不胜感激!
何时能不做牛马:简历每个点之间的间距可以缩一下。几乎没遇到过要演示项目的情况,即使万一遇上了你也可以说部署在其他电脑上本地没代码。nku不应该简历挂吧?抓紧背背八股练练表达,不要放弃,五六月份找到也不晚(不然还得提前入职
应届生简历当中,HR最关...
点赞 评论 收藏
分享
评论
4
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务