逆元 inv
应用于取模运算中
加法 (a + b) % p = a % p + b % p;
减法 (a - b) % p = a % p - b % p;
乘法 (a * b) % p = a % p * b % p;
但是除法
(a / b) % p :
a * b % p = c;
已知 b, c, p 求 a
a = c * d % p
c就是b的逆元
一个数逆元求法
推导过程
第二种求法(推荐)
用快速幂o(log(b)
代码实现
ll pow_mod(ll a, ll b, ll p){
ll ret = 1%p;
while(b){
if(b&1) ret = ret * 1ll * a % p;
a = a * 1ll * a % p;
b >>= 1;
}
return ret;
}
好了现在知道了逆元求法,说题目
打表发现有一个规律,n的排列组合的lcm就是(1到n+1)的lcm/(n+1) % mod
知道了逆元求法,n+1解决了,那么1-n+1的lcm怎么求?
官方题解
因为p的1次2次3次这些数都是只有一个的2,4,8,16这种,一旦出现n =pow(p,k)那么说明要乘上一个最小质因子
/************************************************
* Author :Powatr
* Created Time :2015-8-21 14:10:33
* File Name :1002.cpp
************************************************/
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <cstring>
#include <cmath>
#include <string>
#include <vector>
#include <queue>
#include <deque>
#include <stack>
#include <list>
#include <map>
#include <set>
#include <bitset>
#include <cstdlib>
#include <ctime>
using namespace std;
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
typedef long long ll;
const int MAXN = 1e6 + 10;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
ll prim[MAXN];
ll f[MAXN];
bool ok(ll x)
{
ll y = prim[x];
while(x%y == 0 && x > 1) x/=y;
if(x == 1) return true;
return false;
}
void inti()
{
for(int i = 1; i <= MAXN; i++)
prim[i] = i;
for(int i = 2; i <= MAXN; i++){
if(prim[i] == i){
for(int j = i + i; j <= MAXN; j += i){
prim[j] = i;
}
}
}
f[0] = 1;
for(int i = 1; i <= MAXN; i++){
if(ok(i)) f[i] = f[i-1] * prim[i] % mod;
else f[i] = f[i-1];
}
}
ll pow_mod(ll a, ll b, ll p){
ll ret = 1%p;
while(b){
if(b&1) ret = ret * 1ll * a % p;
a = a * 1ll * a % p;
b >>= 1;
}
return ret;
}
ll inv(ll a, ll b){
return pow_mod(a, b-2, b);
}
int main(){
//Eular();
inti();
int T, n;
for(scanf("%d", &T); T--; ){
scanf("%d", &n);
n++;
ll ans = f[n] * inv(n, mod) % mod;
printf("%I64d\n", ans);
}
return 0;
}