唯一分解定理:任何一个数都可以唯一分解为几个质数的幂次乘积。
const int maxn = 1e6+5; int p[maxn], c[maxn]; int cnt = 0; void divided(int n){ for(int i = 2; i * i <= n; i++){ if(n % i == 0){ p[++cnt] = i; c[cnt] = 0; while(n % i == 0) n /= i, c[cnt]++; } } if(n > 1) p[++cnt] = n, c[cnt] = 1; }求1~n之内的数,因子为2的个数,即是求n!这个数中因子为2的个数
int sum = 0;
while(n){
sum += n/2;
n /= 2;
}
ull fun(ull n, ull x){ ull res = 0; while(n){ res += n / x; n /= x; } return res; }
例题:codeforcesC. Primes and Multiplication
直接分解x,得到唯一分解,然后求每个因子在1~n中出现的次数(使用阶乘的因式分解),然后用快速幂求解。
#include<bits/stdc++.h> using namespace std; typedef unsigned long long ull; const ull mod = 1e9+7; const int maxn = 1e6+5; ull p[maxn], c[maxn]; int cnt = 0; void divided(ull n){ for(ull i = 2; i * i <= n; i++){ if(n % i == 0){ p[++cnt] = i; c[cnt] = 0; while(n % i == 0) n /= i, c[cnt]++; } } if(n > 1) p[++cnt] = n, c[cnt] = 1; } ull fun(ull n, ull x){ ull res = 0; while(n){ res += n / x; n /= x; } return res; } ull quick_mod(ull x, ull n){ ull res = 1; while(n > 0){ if(n & 1) res = res * x % mod; x = x * x % mod; n >>= 1; } return res; } int main() { ull x, n; scanf("%llu%llu", &x, &n); divided(x); ull ans = 1; for(int i = 1; i <= cnt; i++){ ull pp = p[i]; ull num = fun(n, pp); ans *= quick_mod(pp, num); //printf("%llu %llu\n", pp, num); ans %= mod; } printf("%llu\n", ans); return 0; }