Wannafly交流赛1: B. 白兔的式子(组合数)
2018-03-10 02:07
309 查看
链接:https://www.nowcoder.com/acm/contest/73/B
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
有T组询问,每次给出a,b,n,m,求f
[m] mod (998244353)
先说找规律猜公式的方法:
题目中的公式:f[1][1]=1, f[i][j]=a*f[i-1][j]+b*f[i-1][j-1]
不会的话打表找规律呗,然而数据实在是难看出规律,然后仔细看看你会发现:
当a = b = 1的时候f[x][y]不就是组合数C(x-1, y-1)嘛!
(为什么要-1,因为题目中f[1][1]为1其它位置都为0,所以其实错位了,F[1][1]就是C(0, 0))
这样就好办了,这就说明一点:这道题的公式F(n, m)满足当a=b=1时,F(n, m) = C(n-1, m-1)!
也就是说,公式一定是
的形式!那么这个时候再根据表猜x和y就OK了(x=n-m, y=m-1)
再说下推公式方法:
a = b = 1的时候f[x][y]是组合数C(x-1, y-1),而组合数C(n, m)其实是(a+b)^n二项式展开后第m+1项的常数
而刚好a=b=1时C(n, m)就是(1+1)^n二项式展开后的第m+1项,也就是说答案就是(a+b)^(n-1)的第m项
#include<stdio.h>
#define LL long long
#define mod 998244353
LL Pow(LL a, LL b);
LL C(LL m, LL n);
LL Lucas(LL m, LL n);
LL inv[100005] = {1}, jc[100005] = {1};
int main(void)
{
LL T, m, n, i, a, b;
for(i=1;i<=100001;i++)
jc[i] = (jc[i-1]*i)%mod;
inv[100001] = Pow(jc[100001], mod-2);
for(i=100000;i>=1;i--)
inv[i] = inv[i+1]*(i+1)%mod;
scanf("%lld", &T);
while(T--)
{
scanf("%lld%lld%lld%lld", &a, &b, &n, &m);
if(n-m<0)
printf("0\n");
else
printf("%lld\n", C(n-1, m-1)*Pow(a, n-m)%mod*Pow(b, m-1)%mod);
}
return 0;
}
LL Pow(LL a, LL b)
{
LL ans;
ans = 1;
while(b)
{
if(b%2==1)
ans = (ans*a)%mod;
a = (a*a)%mod;
b /= 2;
}
return ans;
}
LL C(LL n, LL m)
{
LL ans;
if(n<m)
return 0;
ans = jc
*inv[m]%mod*inv[n-m]%mod;
return ans;
}
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
已知f[1][1]=1,f[i][j]=a*f[i-1][j]+b*f[i-1][j-1](i>=2,1<=j<=i)。 对于其他情况f[i][j]=0有T组询问,每次给出a,b,n,m,求f
[m] mod (998244353)
输入描述:
第一行为一个整数T,表示询问个数。 接下来一共T行,每行四个整数a,b,n,m。
输出描述:
一共T行,每行一个整数,表示f [m] mod (998244353)
先说找规律猜公式的方法:
题目中的公式:f[1][1]=1, f[i][j]=a*f[i-1][j]+b*f[i-1][j-1]
不会的话打表找规律呗,然而数据实在是难看出规律,然后仔细看看你会发现:
当a = b = 1的时候f[x][y]不就是组合数C(x-1, y-1)嘛!
(为什么要-1,因为题目中f[1][1]为1其它位置都为0,所以其实错位了,F[1][1]就是C(0, 0))
这样就好办了,这就说明一点:这道题的公式F(n, m)满足当a=b=1时,F(n, m) = C(n-1, m-1)!
也就是说,公式一定是
的形式!那么这个时候再根据表猜x和y就OK了(x=n-m, y=m-1)
再说下推公式方法:
a = b = 1的时候f[x][y]是组合数C(x-1, y-1),而组合数C(n, m)其实是(a+b)^n二项式展开后第m+1项的常数
而刚好a=b=1时C(n, m)就是(1+1)^n二项式展开后的第m+1项,也就是说答案就是(a+b)^(n-1)的第m项
#include<stdio.h>
#define LL long long
#define mod 998244353
LL Pow(LL a, LL b);
LL C(LL m, LL n);
LL Lucas(LL m, LL n);
LL inv[100005] = {1}, jc[100005] = {1};
int main(void)
{
LL T, m, n, i, a, b;
for(i=1;i<=100001;i++)
jc[i] = (jc[i-1]*i)%mod;
inv[100001] = Pow(jc[100001], mod-2);
for(i=100000;i>=1;i--)
inv[i] = inv[i+1]*(i+1)%mod;
scanf("%lld", &T);
while(T--)
{
scanf("%lld%lld%lld%lld", &a, &b, &n, &m);
if(n-m<0)
printf("0\n");
else
printf("%lld\n", C(n-1, m-1)*Pow(a, n-m)%mod*Pow(b, m-1)%mod);
}
return 0;
}
LL Pow(LL a, LL b)
{
LL ans;
ans = 1;
while(b)
{
if(b%2==1)
ans = (ans*a)%mod;
a = (a*a)%mod;
b /= 2;
}
return ans;
}
LL C(LL n, LL m)
{
LL ans;
if(n<m)
return 0;
ans = jc
*inv[m]%mod*inv[n-m]%mod;
return ans;
}
相关文章推荐
- Wannafly挑战赛11 白兔的式子 (组合数取模)
- Wannafly挑战赛11-白兔的式子(组合数取模)
- Wannafly挑战赛11 B 白兔的式子【阶乘逆元 + 预处理 + 板子】
- Wannafly挑战赛11 B-白兔的式子
- Wannafly 挑战赛11 B白兔的式子
- Wannafly挑战赛11 B、白兔的式子
- Wannafly挑战赛11 白兔的式子
- Wannafly交流赛1: D. 白兔的字符串(随机+EXKMP)
- Wannafly交流赛1 _A_有理数 【水】
- wannafly交流赛1D(对偶图->最短路)
- 白兔的式子(费马小定理+逆元)
- Wannafly挑战赛11 D 白兔的字符串 [Hash]
- Wannafly交流赛1_B_硬币【数学】
- Wannafly交流赛1-D-迷宫2(最短路)
- Wannafly挑战赛11 - 白兔的分身术
- Wannafly交流赛1: C. 腰带图(瞎搞)
- Wannafly交流赛1 迷宫2 多源最短路
- 白兔的式子(卢卡斯定理+费马小定理求逆元)
- Wannafly交流赛1
- Wannafly交流赛1_牛客网-B 硬币