【队内赛 T2】【数学】巡回的梦魇之神喜欢数列

38 篇文章 0 订阅
本文解析了梦魇之神的难题,涉及数列求解技巧,通过拆分和合并分数形式,利用阶乘和逆元概念,提出了一种高效解决方法。编码部分展示了如何用C++实现,特别是针对大数阶乘计算的逆元求解策略,复杂度为O(T·lgn)。
摘要由CSDN通过智能技术生成

巡回的梦魇之神喜欢数列

队内赛 T2 巡回的梦魇之神喜欢数列


题目

在这里插入图片描述
输入输出样例
输入 #1

3
3 2
4 5
5 10

输出 #1

4
70
2002

输入 #2

10
548663 274643
691753 303423
272071 784649
445453 338151
943278 472896
935376 506928
466125 884296
645556 201996
901126 364020
729913 617772

输出 #2

940823646
795574192
329639602
510984487
583021519
374869018
732112691
34420445
555105650
285447896

在这里插入图片描述


解题思路

先将 a 1 , 2 , 3 , . . . a_{1,2,3,...} a1,2,3,...的式子拆一下( a 1 = k , a 2 = k 2 ( k + 1 ) , a 3 = k 3 ( k 2 ( k + 1 ) + k + 1 ) , . . . a_1 = k, a_2 = \frac{k}{2}(k + 1), a_3 = \frac{k}{3}(\frac{k}{2}(k + 1) + k + 1),... a1=k,a2=2k(k+1),a3=3k(2k(k+1)+k+1),...)
把分数合并一下( a 1 = k 1 , a 2 = k 2 ∗ ( k + 1 ) , a 3 = k 3 ( k + 1 ) ∗ k + 2 2 , . . . a_1=\frac{k}{1}, a_2 = \frac{k}{2}*(k+1), a_3 = \frac{k}{3}(k + 1)*\frac{k+2}{2},... a1=1k,a2=2k(k+1),a3=3k(k+1)2k+2,...)

a n = k n ∗ k + 1 1 ∗ k + 2 2 ∗ . . . ∗ k + n − 1 n − 1 = k ∗ ( k + 1 ) ∗ ( k + 2 ) ∗ . . . ∗ ( k + n − 1 ) 1 ∗ 2 ∗ 3 ∗ . . . ∗ n a_n = \frac{k}{n}*\frac{k+1}{1}*\frac{k+2}{2}*...*\frac{k+n-1}{n-1}=\frac{k * (k + 1) * (k + 2)*...*(k+n-1)}{1*2*3*...*n} an=nk1k+12k+2...n1k+n1=123...nk(k+1)(k+2)...(k+n1)
分母为 n 的阶乘,分子其实就是 (k + n - 1)! / (k - 1)!
因为要%所以要用逆元

这题不能用线性求逆元,因为阶乘很大,导致 inv[] 下标会超,所以只能实时求逆元
复杂度O(T·lgn)


Code

#include <bits/stdc++.h>
#define P 1000000007
#define N 10000100
#define ll unsigned long long

using namespace std;

ll jc[N], inv[N];
ll T, n, k;

ll ksm(ll a, ll b) {
	ll ans = 1;
	for(; b; b >>= 1, a = a * a % P)
		if(b & 1) ans = ans * a % P;
	return ans;
}

int main() {
	jc[0] = jc[1] = 1;
	inv[1] = 1;
	for(int i = 2; i <= N - 100; i ++)
		jc[i] = jc[i - 1] * i % P;
	scanf("%lld", &T);
	while(T --) {
		scanf("%lld %lld", &n, &k);
		printf("%lld\n", jc[k + n - 1] * ksm(jc[k - 1], P - 2) % P * ksm(jc[n], P - 2) % P);
	}
} 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值