校内测之zay与银临 (day2)(只有T1)

一些与题目无关的碎碎念

推出式子来一定要化简!!!freopen不要写错!!!特判不要瞎搞!!!!

做到以上三点能高35分qwq

T1 江城唱晚

你看数据那么大,显然又是一道数学题。

这里有n个种海棠的坑,我们要种m个(还不能挨着种,虽然不知道是什么原理)

那我们不妨先把不种海棠的坑那出来,最后再差回去

如果拿出来的坑的数量还不够m,最后肯定无法保证每两棵海棠之间至少隔1个空,这就是无解情况。然而数据保证有解,就不特判了(只是因为懒)

现在只有m个坑了。因为编号不同的花种在同一位置也是一种新的方案,所以这m棵花的所有排列方式是种,由公式得=m!

我们再把拿出来的n-m个坑差回去。因为n-m>=m,所以我们倒着来,把m个有花的坑插在n-m+1个地方。

解释一下为什么是n-m+1

 其中,黑色的是不种花的坑,粉色的是种花的坑可以放的地方

在n-m+1个空中任选m个的方案数是什么呢?

zhx的小学老师说是

综上,方案数:

 

也就是  (n-m+1)!/(m!*(n-2m+1)!*m!

化简一下:(n-m+1)!/(n-2m+1)!=(n-2m+2)*(n-2m+3)*.....*(n-m+1)

似乎没法再化简了,那就暴力乘起来呗

就有了代码

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;
long long m,mod,n,type,ans=1;
inline long long read()
{
    char ch=getchar();
    long long x=0;bool flag=0;
    while(ch<'0'||ch>'9')
    {
        if(ch=='-')flag=1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
    {
        x=(x<<3)+(x<<1)+(ch^48);
        ch=getchar();
    }
    if(flag)x=-x;
    return x;
}
int main()
{
    freopen("ilove.in","r",stdin);//别写错了
    freopen("ilove.out","w",stdout);
    type=read();n=read();m=read();mod=read();//既然type自己觉得没有什么用就不要乱特判了
     for(int i=n-2*m+2;i<=n-m+1;i++)
      ans=ans*i%mod;
    printf("%lld",ans);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/lcez56jsy/p/11082723.html