题解——[yLOI2019]青原樱(数学组合)
思路相当好,和小凯的疑惑是一个档次的题
传送门:[yLOI2019] 青原樱
题面
Description
扶苏是一个非常喜欢边听古风鸽边写数学题的人,因此这道题其实是个五三原题。
扶苏希望重现青原上樱花盛开的景色,于是他准备了很多互不相同樱花树幼苗,准备种成一行。
这一行中,一共有 nn 个位置可以种下樱花,而扶苏准备了 mm 支幼苗。由于樱花盛放时对左右空间需求非常大,所以樱花不能紧挨着种植,也就是任意两支幼苗之间必须至少存在一个不种花的空位置。
按照这种方式种花并不难,但是令扶苏感到好奇的是一共有多少合法的方案让他把这 mm 支幼苗都种下去。一个方案是合法的当且仅当他满足上一段中叙述的要求。如果我们将花按照 1,2,3dotsm1, 2, 3 … m 编号,两种方案不同当且仅当被选择种花的位置不同或从左向右数花的编号序列不同。
为了避免输出过大,答案对一个参数 pp 取模。
Input
每个输入文件中有且仅有一组测试数据。
测试数据只有一行四个数字,依次代表 type, n, m, p,其中 type 是一个帮助你判断测试点类型的参数,会在数据范围中说明
Output
输出一行一个数字,代表答案对 p 取模的结果。
in.1
1 3 2 19260718
out.1
2
数据范围与约定
思路
考虑将每个树苗和他后面的空位作为一个物体,最后一个位置要做的单独作为一种情况。两种情况乘上!m 求和后化简为求A( m,n-m+1 )
膜拜原作者兼出题人:-扶苏-。
详情见:A [yLOI2019] 青原樱
AC code:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll type , N , M , mod , ans = 1LL;
int main() {
scanf("%lld%lld%lld%lld", &type , &N , &M , &mod ) ;
ll tot = N - 2*M +1 ;
for( ll i = tot+1 ; i <= tot+M ; ++i )ans = i*ans%mod;
cout<<ans ;
return 0;
}