病毒扩散

链接:

时间限制:C/C++ 2秒,其他语言4秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200429210705568.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM1OTc1MzY3,size_16,color_FFFFFF,t_70在这里插入图片描述
牛牛想知道,对于特殊的 \ n n 个点,在时刻\ t t 感染者的数量。
输入描述:
在这里插入图片描述

输出描述:
对于每一个特殊的点,输出一行一个非负整数,表示在 \ t t 时刻这个点的感染者数量,对 998244353 取模。
示例1
输入
复制
3
0 0 1
1 1 2
2 0 2
输出
复制
1
2
1
说明
见题目描述中的图片。
示例2
输入
复制
5
5 5 7
2 7 9
0 14 14
0 14 15
14 29 100
输出
复制
0
36
1
15
891148910
备注:
在这里插入图片描述
题解:
我们可以转化下题意:

从(0,0)出发,每次可以走一步,或者原地不动,问t时刻走到(x,y)的方案数量

想想这个怎么做?不会
因为一次最多走一步,所以到(x,y)至少要走x+y个时刻,
我们设sum=x+y,sum一定要大于t否则怎么能走到,要在t时刻内走到,就是在t内选sum个时刻,共有Ctsum
在移动的sum个步数里,有x步需要x坐标加一,其余要将y坐标加一,一共有Cxsum
综上,乘在一起就可以

还一个想法:一共t时刻,其中选出x个用于x坐标加一,剩下t-x中选出y个用于y坐标加一,剩下的原地不动
这样就是Cxt*Cyt-x
求组合数时,
乘法逆元:(a/b)% mod = a * b^(mod-2),mod为素数
代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 7;
const int mod = 998244353;
ll poww(ll a, ll b)
{
    ll ans = 1;
    a = a % mod;
    while (b)
    {
        if(b & 1) ans = (ans* a) % mod;
        a = ( a*a )% mod;
        b = b >> 1;
    }
    return ans;
}
 
ll c[maxn];
int main()
{
 	int n;
 	ll c1,c2;
    c[1]=1,c[0]=1;
    for( ll i=2;i<maxn;i++ ) c[i]=(c[i-1]*i)%mod;
    
    scanf("%d",&n);
    while( n-- )
    {
        int a,b,t;
        scanf("%d%d%d",&a,&b,&t);
        if( a+b>t )
        {
            cout<<"0"<<endl;
            continue;
        }
         c1=( c[t] * poww( c[t-b] * c[b], mod - 2) ) % mod;
         c2=( c[t-b] * poww( c[t-b-a] * c[a], mod - 2) ) % mod;
        printf("%lld\n",(c1*c2)%mod);
    }
    return 0;
}

我看还有一个是找规律,用杨辉三角形做的,tql

posted @ 2020-04-29 21:40  回归梦想  阅读(84)  评论(0编辑  收藏  举报