题解链接:http://icebound.cc/2019/05/25/hbcpc2019.html
文章目录
热身赛 511
Description
给定n,m,请你计算[1,n!]范围内有多少数字能被m整除。由于答案很大,请输出答案对10e9+7取模的结果。
Input
第一行一个整数T,代表接下来有T组数据
接下来每组数据,有两个数字n,m
1<n,m<=1e6
Output
输出答案对10e9+7取模的结果。
Sample input
2
9 3
10 9
Sample output
120960
403200
题意为求 ( n ! / m ) m o d M (n!/ m)~mod~M (n!/m) mod M,可以利用费马小定理将原式化为:
( n ! ∗ m M − 2 ) m o d M (n!*m^{M-2})~mod~M (n!∗mM−2) mod M
再根据乘法的取模公式,进一步将式子化为:
( n ! m o d M ∗ m M − 2 m o d M ) m o d M (n!~mod~M*m^{M-2}~mod~M)~mod~M (n! mod M∗mM−2 mod M) mod M
左边的 n ! m o d M n!~mod~M n! mod M 可以进一步拆分为
[ n m o d M ∗ ( n − 1 ) m o d M ∗ . . . . . . ∗ 1 m o d M ] m o d M [n~mod~M*(n-1)~mod~M*......*1~mod~M]~mod~M [n mod M∗(n−1) mod M∗......∗1 mod M] mod M
右边的 m M − 2 m o d M m^{M-2}~mod~M mM−2 mod M则可以利用快速幂解出
#include <iostream>
#include <algorithm>
using namespace std;
const int M = 1e9 + 7;
const int N = 1e6 + 5;
typedef long long ll;
ll res[N];
ll mod_pow(ll x, ll n, ll mod)
{
ll res = 1;
while (n > 0) {
if (n & 1) res = res * x % mod;
x = x * x % mod;
n >>=