p = 998244353 deffastpow(a, n): base, res = a, 1 while n != 0: if n & 1: #取最后一位二进制数,看是否为1 res = res * base % p base = base * base % p n >>= 1 return res%p """自带的快速幂""" pow(a,b,p) # a^b mod p
classFactorial: def__init__(self, N, mod) -> None: self.mod = mod self.f = [1for _ inrange(N)] self.g = [1for _ inrange(N)] for i inrange(1, N): self.f[i] = self.f[i - 1] * i % self.mod self.g[-1] = pow(self.f[-1], mod - 2, mod) for i inrange(N - 2, -1, -1): self.g[i] = self.g[i + 1] * (i + 1) % self.mod defcomb(self, n, m): if n < 0or m < 0or n < m: return0 return self.f[n] * self.g[m] % self.mod * self.g[n - m] % self.mod defperm(self, n, m): if n < 0or m < 0or n < m: return0 return self.f[n] * self.g[n - m] % self.mod defcatalan(self, n): # TODO: check 2 * n < N# return (self.comb(2 * n, n) - self.comb(2 * n, n - 1)) % self.mod # N个不同的物品放进m个不同的集合,保证每个集合都不是空集# defsterling(self, n, m): if n < m: return0 else: res = 0 for i inrange(m + 1): t = self.comb(m, i) * pow(m - i, n, self.mod) % self.mod if i & 1: res -= t else: res += t res %= self.mod return res * self.g[m] % self.mod n,m = map(int,input().split()) t = Factorial(n+1,int(1e9) + 7) print(t.sterling(n,m))
1、质数
从 到 中有 个质数
(1) 判定(试除法)
1 2 3 4 5 6
defis_primer(n): i = 2 while i <= n // i: if n % i == 0: returnFalse i += 1 returnTrue
(2)分解质因数(试除法)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
primes,c = [],[] defdivide(n): i = 2 while i*i <= n: if n % i == 0: cnt = 0 while n % i == 0: n //= i cnt += 1 primes.append(i) # i 为质因数,cnt 为对应的指数 c.append(cnt) i += 1 if n > 1: primes.append(n) c.append(1)
如果有多次询问:当然可以预处理质数O(sqrt(n)),每次询问O(sqrt(n)/log(n))
(3)埃氏筛法
1 2 3 4 5 6 7
ls, primes = [0]*(n+1), [] defget_primes(n): for i inrange(2, int(sqrt(n))+1): ifnot ls[i]: primes.append(i) for j inrange(i+i, n+1, i): ls[j] = 1
for i inrange(2, MAXN): if is_prime[i]: prime.append(i) for j inrange(i*i, MAXN, i): is_prime[j] = 0 defsolve(): l, r = map(int, sys.stdin.readline().split()) if l == 1: l += 1#不处理的话,1会筛不掉 n = r - l + 1 if n < 2: return vis = [0] * n for p in prime: if p > r: break for i inrange((l+p-1)//p * p, r//p*p+1, p): if i == p: continue vis[i-l] = 1 ls = [] for i inrange(n): if vis[i]: continue ls.append(i)
(5)线性筛法(确保了每个被筛掉的合数都是由其最小质因子筛掉的)
当 时,由于我们是从小到大遍历质数,所以 是 的最小质因子,也是 的最小质因子。
当 时, 小于 的最小质因子,所以也是 的最小质因子。
1 2 3 4 5 6 7 8 9 10
N = 3*10**5 is_prime = [1]*(N+1) primes = [] for i inrange(2,N+1): if is_prime[i]: primes.append(i) j = 0 while primes[j] <= N//i: is_prime[primes[j]*i] = 0 if i % primes[j] == 0: break j += 1
2、约数
(1)扩展欧几里得算法
所以:
又 $a \mod b = a - a//bbax + by = b(x’ - a//by’) + ay’ = d$
即:
1 2 3 4
defexgcd(a, b): if b == 0: return [a, 1, 0] [g, x, y] = exgcd(b, a % b) return [g, y, x - a // b * y]