牛客练习赛62 B-病毒扩散
这是个我不配签到的一次比赛,我太弱了,在线发抖
牛牛所在的城市有一种新型病毒开始扩散。在一个二维平面坐标系上,有一个感染者在 (0,0)\ (0,0) (0,0) 的位置。从 时刻 0\ 0 0 开始,每一个在 (x,y)\ (x,y) (x,y) 的感染者都会让下一个时刻 (x+1,y)\ (x+1,y) (x+1,y), (x,y+1)\ (x,y+1) (x,y+1) 的感染者数量增加 1\ 1 1。
上图展示了时刻 0\text{0}0 和时刻 1\text{1}1 病毒的扩散情况。在时刻 1\ 1 1,(0,0),(0,1),(1,0)\text (0,0),(0,1),(1,0)(0,0),(0,1),(1,0) 的感染者数量为 1\ 1 1。在时刻 2\ 2 2, (0,0),(0,2),(2,0)\ (0,0),(0,2),(2,0) (0,0),(0,2),(2,0) 的感染者数量为 1\ 1 1, (0,1),(1,0),(1,1)\ (0,1),(1,0),(1,1) (0,1),(1,0),(1,1) 的感染者数量为 2\ 2 2。
牛牛想知道,对于特殊的 n\ n n 个点,在时刻 t\ t t 感染者的数量。
上图展示了时刻 0\text{0}0 和时刻 1\text{1}1 病毒的扩散情况。在时刻 1\ 1 1,(0,0),(0,1),(1,0)\text (0,0),(0,1),(1,0)(0,0),(0,1),(1,0) 的感染者数量为 1\ 1 1。在时刻 2\ 2 2, (0,0),(0,2),(2,0)\ (0,0),(0,2),(2,0) (0,0),(0,2),(2,0) 的感染者数量为 1\ 1 1, (0,1),(1,0),(1,1)\ (0,1),(1,0),(1,1) (0,1),(1,0),(1,1) 的感染者数量为 2\ 2 2。
牛牛想知道,对于特殊的 n\ n n 个点,在时刻 t\ t t 感染者的数量。
输入描述:
第一行一个正整数 n\ n n,表示特殊点的数量。
接下来 n\ n n 行,每行三个非负整数 xi,yi,tix_i,y_i,t_ixi,yi,ti,表示有一个特殊的点在 (xi,yi)(x_i,y_i)(xi,yi),牛牛想知道在时刻 tit_iti 这个点有多少感染者。
输出描述:
对于每一个特殊的点,输出一行一个非负整数,表示在 t\ t t 时刻这个点的感染者数量,对 998244353 取模。
示例1
输入
30 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
备注:
1≤n≤105,0≤xi,yi≤1000,0≤ti≤50001\leq n \leq 10^5,0\leq x_i,y_i \leq 1000,0 \leq t_i \leq 50001≤n≤105,0≤xi,yi≤1000,0≤ti≤5000。
这是比赛时我唯一一个可以写的题,还没写出来,我好弱
当时看到就觉得是dfs,但看到数据就WC了,之后盲猜是dp,想了好久把自己绕进去了,写了好几个版本,都是WA~
赛后补题,看了半天大佬题解,才发现是组合数,不过那种求逆元,组合数的方法比较繁琐,看到一个大佬题解,发现竟然可以找出来杨辉三角,强!!!!
于是我决定将这个分享给大家
大佬
因此我们发现这个题目就是一个杨辉三角的运用啊,这就简单多了
剩下所有的关键都是杨辉三角了,那么我们就来看看如何来存储这个杨辉三角
首先,因为时间的限制比位置大,我们的杨辉三角取最大的
对于任意的一组 (x+y), 他们所在的杨辉三角的层数是一样的(都是第x+y层),而且每一层的杨辉三角是对称的,所以对于任意的x,y我们可以对应到第(x+y)层的第x|y的位置。
对于杨辉三角
1 n=1
1 1 n=2
121 n=3
1331 n=4
f[n][i] = f[n-1][i] + f[n-1][i-1]
这是性质
那么我们就可以做了

1 #include <iostream> 2 #include <cstdio> 3 #include <cmath> 4 5 using namespace std; 6 typedef long long ll; 7 const int mod = 998244353; 8 int f[5010][5010]={0}; 9 int main() 10 { 11 int n; 12 cin >> n; 13 f[0][0]=1; 14 for(int i=1;i<=5010;i++) 15 { 16 f[i][0]=1; 17 for(int j= 1;j<=i;j++) 18 { 19 f[i][j] = (f[i-1][j]+f[i-1][j-1])%mod; 20 } 21 } 22 while(n--) 23 { 24 int x,y,t; 25 cin >> x >> y >> t; 26 if(x+y>t){ 27 cout<<"0"<<endl; 28 } 29 else{ 30 cout<< ((ll)f[x+y][y]*f[t][x+y])%mod<<endl; 31 } 32 } 33 return 0; 34 }
后续更新。。。。。