【题解】P4456 [CQOI2018] 交错序列(数学递推)

P4456 CQOI2018 交错序列 - 洛谷 (luogu.com.cn)

时间复杂度线性。

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;

const int N = 1e7 + 10;  
int fac[N], inv[N], P;

int qpow(int a, int b) {
    int c = 1;
    while (b) {
        if (b & 1) c = 1ll * c * a % P;
        a = 1ll * a * a % P;
        b >>= 1;
    }
    return c;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
	
	int n, a, b;
    cin >> n >> a >> b >> P;

    fac[0] = 1;
    for (int i = 1; i <= n + 1; i ++) {
        fac[i] = 1ll * fac[i - 1] * i % P;
    }

	inv[n + 1] = qpow(fac[n + 1], P - 2);   // (n+1)! 的逆元
	for (int i = n; i >= 0; i --)
    	inv[i] = 1ll * inv[i + 1] * (i + 1) % P;

    int ans = 0;
    // 枚举 1 的个数 i(即 y = i)
    for (int i = 0; i <= n; i ++) {
        // 交错序列中 1 不相邻,恰好有 i 个 1 的方案数为 C(n - i + 1, i)
        // 需要满足 i <= n - i + 1,即 2i <= n + 1,否则组合数为 0
        if (i <= n - i + 1) {
            // 组合数 C(n-i+1, i) = fac[n-i+1] * inv[i] * inv[n-2i+1] mod m
            // 这里 n-(i-1) = n-i+1,n-(i-1)-i = n-2i+1
            int comb = 1ll * fac[n - i + 1] * inv[i] % P * inv[n - i + 1 - i] % P;
            // 特征值:x = n - i(0 的个数),y = i(1 的个数)
            // 贡献 = 方案数 * (n-i)^a * i^b
            int term = 1ll * comb * qpow(n - i, a) % P * qpow(i, b) % P;
            ans = (ans + term) % P;
        }
    }

    cout << ans << "\n";
    return 0;
}
相关推荐
特立独行的猫A4 小时前
c++的`std::future` 与 `std::promise` 简明教程(5分钟读完)
c++
特立独行的猫A4 小时前
C++ 异步编程:std::future 与 std::promise 详解(含 RPC 客户端实现实践)
c++·后端
FluxArt4 小时前
GPT Image 2.5 多图参考怎么用:Flux Art 生成与编辑教程
数据结构·gpt·算法
All for pursuit.5 小时前
【分治-2】215.数组中的第K个最大元素
数据结构·c++·算法·leetcode
lcj25115 小时前
【C++】set和map——详细使用说明
开发语言·c++·笔记·面试
潼心1412o5 小时前
C++初阶(长期更新)第3讲:类和对象(中)
开发语言·c++
CQU_JIAKE5 小时前
9.15【A】
算法·动态规划
成为深度学习高手5 小时前
DAG:沿时间与通道双相关建模的外生变量时序预测
网络·人工智能·深度学习·算法·机器学习·数据挖掘·时序数据库
程序喵大人5 小时前
【C++入门】编译链接模型 - 02 预处理把头文件怎样塞进源文件
开发语言·c++·预处理·编译链接·头文件·源文件
阳明山水5 小时前
CEDAR双重解耦实现决策与干预分离
人工智能·深度学习·算法·机器学习·架构