• 数论-约数


    一.试除法求约数:

     1 vector<int> get_divisorts(int t){
     2     vector<int> a;
     3     for(int i = 1;i <= t/i;++i){
     4         if(t % i == 0){
     5             a.push_back(i);
     6             if(i != t/i) a.push_back(t/i);
     7         }
     8     }
     9     return a;
    10 }
    View Code

    二.约数个数:

    公式:由唯一分解定理: X = P1^a + P2^b + ... + Pn^m,约数个数 等于 (a+1) * (b+1) * ... * (m+1)

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 
     5 const int mod = 1e9+7;
     6 
     7 int main(){
     8     unordered_map<int, int> primes;
     9     ll res = 1;
    10     int n;cin >> n;
    11     while(n --){
    12         int x; cin >> x;
    13         //求出唯一分解定理里的每一项
    14         for(int i = 2;i <= x/i;++i){
    15             while(x % i == 0){
    16                 x /= i;
    17                 ++ primes[i];    
    18             }
    19         }
    20         if(x > 1) ++ primes[x];
    21     }
    22     for(auto p : primes) res = res * (p.second+1) % mod;//约数个数等于唯一分解定理里每个指数+1再相乘  
    23     cout << res << endl;
    24     return 0;
    25 }
    View Code

    三.约数之和:

    公式:X = P1^a + P2^b + ... + Pn^m,约数之和 = (p1^0 + p1^1 + ... + p1^a) * (p2^0 + p2^1 + ... p2^b) * ... * (pn^0 + ... + pn^m)

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 typedef long long ll;
     5 const int mod = 1e9+7;
     6 
     7 int main(){
     8     unordered_map<int, int> prime;
     9     int n;cin >> n;
    10     while(n --)
    11     {
    12         int x;cin>> x;
    13         for(int i = 2;i <= x/i;++i){
    14             while(x % i == 0){
    15                 x /= i;
    16                 prime[i]++;
    17             }
    18         }
    19         if(x > 1)prime[x]++;
    20     }
    21     ll res = 1;
    22     for(auto p : prime){
    23         int a = p.first, b = p.second;        
    24         ll t = 1;
    25         while(b--) t = (t * a + 1) % mod;
    26         res =res * t % mod;
    27     }
    28     cout << res << endl;
    29     return 0;
    30 }
    View Code

    四.gcd(欧几里得算法)(辗转相除法):求最大公约数:

    公式:(a, b) = (b, a % b)

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 int gcd(int a, int b){
     5     return b ? gcd(b, a % b) : a;
     6 }
     7 
     8 int main(){
     9     int n;cin >> n;
    10     while(n --){
    11         int a, b;cin >> a >> b;
    12         cout << gcd(a,b) << endl;
    13     }
    14     return 0;
    15 }
    View Code
  • 相关阅读:
    【ZJOI 2008】 生日聚会
    BZOJ2135 刷题计划(贪心+二分)
    BZOJ2124 等差子序列(树状数组+哈希)
    BZOJ2282 SDOI2011消防/NOIP2007树网的核(二分答案+树形dp)
    BZOJ1304 CQOI2009叶子的染色(树形dp)
    BZOJ1283 序列(费用流)
    BZOJ1266 AHOI2006上学路线(最短路+最小割)
    BZOJ1041 HAOI2008圆上的整点(数论)
    BZOJ3505 CQOI2014数三角形(组合数学)
    BZOJ5206 JSOI2017原力(三元环计数)
  • 原文地址:https://www.cnblogs.com/sxq-study/p/12249887.html
Copyright © 2020-2023  润新知