时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 262144K,其他语言524288K 64bit IO Format: %lld
题目描述
牛牛想知道,对于特殊的 \ 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个时刻,共有C^t^sum
在移动的sum个步数里,有x步需要x坐标加一,其余要将y坐标加一,一共有C^x^sum
综上,乘在一起就可以
还一个想法:一共t时刻,其中选出x个用于x坐标加一,剩下t-x中选出y个用于y坐标加一,剩下的原地不动
这样就是C^x^t*C^y^t-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