数论——唯一分解定理
Powered by:AB_IN 局外人
我数论这学的是真烂啊。。。
又得借练习赛补老番……
任意一个大于0的正整数都能被表示成若干个素数的乘积且表示方法是唯一的。这就是唯一分解定理。
用于求 因子和 和 因子个数 。
求因子和
模板
//以线性筛为基础 int jet_num[N];//用来记录素数的幂是多少的 ll get_yin_zi_sum(ll n) { ll ans = 1; for(int i = 1; (ll) prime[i] * prime[i] <= n; i++){ if(!(n % prime[i])){ ll jet = 1, sum = 1; while(!(n % prime[i])){ jet_num[prime[i]]++; jet *= prime[i]; sum += jet; n /= prime[i]; } ans *= sum; } } if(n > 1) { jet_num[n]++; ans *= (n + 1); } return ans; }
五十弦翻塞外声
#include <bits/stdc++.h> #define ll long long const int N=1e6+5; int cnt, prime[N], pre[N]; bool flag[N]; using namespace std; void init() { memset(flag,1,sizeof(flag)); flag[1]=cnt=0; for(int i=2;i<=N;i++) { if(flag[i]) { prime[++cnt]=i; pre[i]=cnt; } for(int j=1;j<=cnt&&prime[j]*i<=N;j++) { flag[prime[j]*i]=0; if(i%prime[j]==0)break; } } } ll get_yin_zi_sum(ll n) { ll ans = 1; for(int i = 1; (ll) prime[i] * prime[i] <= n; i++){ if(!(n % prime[i])) { ll jet = 1, sum = 1; while( !(n % prime[i]) ) { jet *= prime[i]; sum += jet; n /= prime[i]; } ans *= sum; } } if(n > 1) ans *= (n + 1); return ans; } void solve() { ll x; scanf("%lld", &x); printf("%lld\n", get_yin_zi_sum(x)); } int t; int main() { init(); scanf("%d", &t); while(t--){ solve(); } return 0; }
以举例
- , , , ,
- , , , ,
- 此时
(n % prime[i]) != 0
,弹出, - , , , 故
- ,
求因子个数
模板
//以线性筛为基础 ll get_yin_zi_num(ll n) { ll ans = 1; for(int i = 1; (ll) prime[i] * prime[i] <= n; i++){ if(!(n % prime[i])){ ll cnt = 0; while(!(n % prime[i])){ cnt ++; n /= prime[i]; } ans *= (1 + cnt); } } if(n > 1) ans *= 2; return ans; }
//不以线性筛为基础 ll get_yin_zi_num(ll n){ ll ans = 1; for(ll i = 2; i * i <= n; i++){ if( !(n % i)){ ll cnt = 0; while(!(n % i)){ cnt ++; n /= i; } ans *= (1 + cnt); } } if(n > 1) ans *= 2; return ans; }
Vae_1118的行列式
题意是求的因子个数。
#include <bits/stdc++.h> #define ll long long const int N=1e6+5; int cnt,prime[N],pre[N]; bool flag[N]; using namespace std; void init() { memset(flag,1,sizeof(flag)); flag[1]=cnt=0; for(int i=2;i<=N;i++) { if(flag[i]) { prime[++cnt]=i; pre[i]=cnt; } for(int j=1;j<=cnt&&prime[j]*i<=N;j++) { flag[prime[j]*i]=0; if(i%prime[j]==0)break; } } } ll get_yin_zi_num(ll n) { ll ans = 1; for(int i = 1; (ll) prime[i] * prime[i] <= n; i++){ if(!(n % prime[i])){ ll cnt = 0; while(!(n % prime[i])){ cnt ++; n /= prime[i]; } ans *= (1 + cnt); } } if(n > 1) ans *= 2; return ans; } int t,mod; void solve() { ll x; scanf("%lld", &x); printf("%lld\n", get_yin_zi_num(x - 1) % mod); } int main() { init(); scanf("%d%d", &t, &mod); while(t--){ solve(); } return 0; }
以举例
- , , ,
- , , ,
- 此时
(n % prime[i]) != 0
,弹出, - , , , 故
- ,
完结。
#学习路径#