题解:洛谷 P5520 [yLOI2019] 青原樱

【题目来源】

洛谷:P5520 [yLOI2019] 青原樱 - 洛谷

【题目描述】

扶苏是一个非常喜欢边听古风鸽边写数学题的人,因此这道题其实是个五三原题。

扶苏希望重现青原上樱花盛开的景色,于是他准备了很多互不相同樱花树幼苗,准备种成一行。

这一行中,一共有 \(n\) 个位置可以种下樱花,而扶苏准备了 \(m\) 支幼苗。由于樱花盛放时对左右空间需求非常大,所以樱花不能紧挨着种植,也就是任意两支幼苗之间必须至少存在一个不种花的空位置。

按照这种方式种花并不难,但是令扶苏感到好奇的是一共有多少合法的方案让他把这 \(m\) 支幼苗都种下去。一个方案是合法的当且仅当他满足上一段中叙述的要求。如果我们将花按照 \(1,2,3,\dots,m\) 编号,两种方案不同当且仅当被选择种花的位置不同或从左向右数花的编号序列不同。

为了避免输出过大,答案对一个参数 \(p\) 取模。

【输入】

每个输入文件中有且仅有一组测试数据。

测试数据只有一行四个整数,依次代表 \(type,~n,~m,~p\),其中 \(type\) 是一个帮助你判断测试点类型的参数,会在数据范围中说明。

【输出】

输出一行一个整数,代表答案对 \(p\) 取模的结果。

【输入样例】

1 3 2 19260718

【输出样例】

2

【解题思路】

image

【算法标签】

《洛谷 P5520 青原樱》 #动态规划DP# #数学# #组合数学# #排列组合# #2019# #O2优化#

【代码详解】

#include <bits/stdc++.h>
using namespace std;
#define int long long
int type, n, m, p, ans = 1;

signed main()
{
    cin >> type >> n >> m >> p;  // 输入:type(题目类型,但未使用), n(总数), m(每组人数), p(模数)
  
    n -= (m-1);  // 关键操作:从n中减去(m-1),相当于n = n - m + 1
  
    // 计算乘积:从(n-m+1)到n的m个连续整数的乘积
    for (int i = n - m + 1; i <= n; i++)
    {
        ans *= i;    // 连乘
        ans %= p;    // 每次乘法后取模,防止溢出
    }
  
    cout << ans << endl;  // 输出结果
    return 0;
}

【运行结果】

1 3 2 19260718
2
posted @ 2026-02-20 20:29  团爸讲算法  阅读(1)  评论(0)    收藏  举报