日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

第四章 数学知识【完结】

發布時間:2025/3/20 编程问答 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 第四章 数学知识【完结】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本文的所有內容模板都來自于y總

目錄

  • 試除法判定質數
  • 試除法分解質因數
  • 樸素篩法求素數
  • 埃氏篩法求素數
  • 線性篩法
  • 試除法求所有約數
  • 約數個數和約數之和
  • 歐幾里得算法
  • 求歐拉函數
  • 篩法求歐拉函數 【不熟】
  • 快速冪
  • 擴展歐幾里得算法
  • 中國剩余定理 【未解決】
  • 高斯消元 【不熟】
  • 求組合數 【不熟】
  • 容斥定理 【不熟】
  • 博弈論【不會】

試除法判定質數

866. 試除法判定質數
時間復雜度是根號n

bool is_prime(int x) {if (x < 2) return false;for (int i = 2; i <= x / i; i ++ )if (x % i == 0)return false;return true; }

試除法分解質因數

867. 分解質因數
時間復雜度是 logn 到根號n 之間

void divide(int x) {for (int i = 2; i <= x / i; i ++ )if (x % i == 0){int s = 0;while (x % i == 0) x /= i, s ++ ;cout << i << ' ' << s << endl;}if (x > 1) cout << x << ' ' << 1 << endl; //這是說明結果是 類似于 86 =2*43 43不可再分了這種情況cout << endl; }

樸素篩法求素數

時間復雜度: O(nlogn)

int primes[N], cnt; // primes[]存儲所有素數 bool st[N]; // st[x]存儲x是否被篩掉void get_primes(int n) {for (int i = 2; i <= n; i ++ ){if (st[i]) continue;primes[cnt ++ ] = i;for (int j = i + i; j <= n; j += i)st[j] = true;} }

埃氏篩法求素數

時間復雜度: O(nloglogn)

int cnt; // 存儲素數個數 bool hush[N]; // st[x]存儲x是否被篩掉 for(int i=2;i<=n;i++){if(!hush[i]){cnt++;for(int j=i+i;j<=n;j+=i) hush[j]=true;}}

線性篩法

868. 篩質數
你會發現: 用埃氏篩法的話,有一些數是篩了多遍的。
例: 6 用 2篩過一遍,用3又篩過一遍。

那么線性篩法就來了,它對于每一個數都只篩一遍是線性的,當要篩的數特別多的時候。
線性篩法幾乎快埃氏篩法一倍的速度。
下面的總結來自于: Acwing的評論區,我從中摘抄了里面的精華。
線性篩法的原理:

  • 核心:1~n內的合數只會被其最小質因子篩掉.
  • 原理:1~n之內的任何一個合數一定會被篩掉,而且篩的時候只用最小質因子來篩,
    然后每一個數都只有一個最小質因子,因此每個數都只會被篩一次,因此線性篩法是線性的.
int primes[N], cnt; // primes[]存儲所有素數 bool st[N]; // st[x]存儲x是否被篩掉void get_primes(int n) {for (int i = 2; i <= n; i ++ ){if (!st[i]) primes[cnt ++ ] = i;for (int j = 0; primes[j] <= n / i; j ++ ){st[primes[j] * i] = true;if (i % primes[j] == 0) break;}} }

關于線性篩的解釋:
枚舉到i的最小質因子的時候就會停下來,即”if(i%primes[j]==0) break;”。
因為從小到大枚舉的所有質數,所以當”i%primes[j]!=0”時,primes[j]一定小于i的最小質因子,
primes[j]一定是primes[j]i的最小質因子.
因為是從小到大枚舉的所有質數,所以當”i%primes[j]==0”時,primes[j]一定是i的最小質因子,
而primes[j]又是primes[j]的最小質因子,因此primes[j]是iprimes[j]的最小質因子.
關于for循環的解釋:
注:首先要把握住一個重點:我們枚舉的時候是從小到大枚舉的所有質數

  • 1.當i%primes[j]==0時,因為是從小到大枚舉的所有質數,所以primes[j]就是i的最小質因子,而primes[j]又是其本身
    primes[j]的最小質因子,因此當i%primes[j]==0時,primes[j]是primes[j]i的最小質因子.
  • 2.當i%primes[j]!=0時,因為是從小到大枚舉的所有質數,且此時并沒有出現過有質數滿足i%primes[j]==0,
    因此此時的primes[j]一定小于i的最小質因子,而primes[j]又是其本身primes[j]的最小質因子,
    所以當i%primes[j]!=0時,primes[j]也是primes[j]i的最小質因子.
  • 3.綜合1,2得知,在內層for循環里面無論何時,primes[j]都是primes[j]i的最小質因子,因此”st[primes[j]i]=true”
    語句就是用primes[j]i這個數的最小質因子來篩掉這個數.

for (int j = 0; primes[j] <= n / i; j ++)不需要寫成 for (int j = 0; j < cnt && primes[j] <= n / i; j ++)理由:
如果 i 是合數,那它有最小質因子 prime[j],所以循環會在枚舉到 prime[j] 時 break 掉;
如果 i 是質數,則由于上面剛把 i 加到了 primes 數組中,所以 prime[j] 枚舉到最后一個時正好等于 i,
所以也會 break 掉。因此 j 不會大于等于當前的 cnt

試除法求所有約數

869. 試除法求約數

vector<int> get_divisors(int x) {vector<int> res;for (int i = 1; i <= x / i; i ++ )if (x % i == 0){res.push_back(i);if (i != x / i) res.push_back(x / i);//避免 36 6*6 進入2個6的情況}sort(res.begin(), res.end());return res; }

約數個數和約數之和

870. 約數個數
871. 約數之和

如果 N = p1^c1 * p2^c2 * ... *pk^ck 約數個數: (c1 + 1) * (c2 + 1) * ... * (ck + 1) 約數之和: (p1^0 + p1^1 + ... + p1^c1) * ... * (pk^0 + pk^1 + ... + pk^ck)

約數個數公式的解析:

約數之和公式解析:

歐幾里得算法

872. 最大公約數

int gcd(int a, int b) {return b ? gcd(b, a % b) : a; }

求歐拉函數


873. 歐拉函數

int phi(int x) {int res = x;for (int i = 2; i <= x / i; i ++ )if (x % i == 0){res = res / i * (i - 1);while (x % i == 0) x /= i;}if (x > 1) res = res / x * (x - 1);return res; }

篩法求歐拉函數 【不熟】

874. 篩法求歐拉函數

int primes[N], cnt; // primes[]存儲所有素數 int euler[N]; // 存儲每個數的歐拉函數 bool st[N]; // st[x]存儲x是否被篩掉void get_eulers(int n) {euler[1] = 1;for (int i = 2; i <= n; i ++ ){if (!st[i]){primes[cnt ++ ] = i;euler[i] = i - 1;}for (int j = 0; primes[j] <= n / i; j ++ ){int t = primes[j] * i;st[t] = true;if (i % primes[j] == 0){euler[t] = euler[i] * primes[j];break;}euler[t] = euler[i] * (primes[j] - 1);}} }

快速冪

875. 快速冪
876. 快速冪求逆元
迭代法:

求 m^k mod p,時間復雜度 O(logk)int qmi(int m, int k, int p) {int res = 1 % p, t = m;while (k){if (k&1) res = res * t % p;t = t * t % p;k >>= 1;}return res; }

遞歸法:

#include<cstdio> #include<iostream> using namespace std; typedef long long int ll; ll f(ll a,ll b,ll c) {if(!b) return 1;ll res=f(a,b>>1,c);if(b&1) return a*res%c*res%c;else return res*res%c; } int main(void) {int n; scanf("%d",&n);while(n--){ll a,b,c; scanf("%lld%lld%lld",&a,&b,&c);cout<<f(a,b,c)<<endl;}return 0; }

擴展歐幾里得算法

877. 擴展歐幾里得算法
878. 線性同余方程

中國剩余定理 【未解決】

204. 表達整數的奇怪方式

高斯消元 【不熟】

883. 高斯消元解線性方程組
884. 高斯消元解異或線性方程組

求組合數 【不熟】

885. 求組合數 I
886. 求組合數 II
887. 求組合數 III
888. 求組合數 IV
AcWing 889. 滿足條件的01序列 【卡特蘭數】

容斥定理 【不熟】

890. 能被整除的數

博弈論【不會】

891. Nim游戲
892. 臺階-Nim游戲
893. 集合-Nim游戲
894. 拆分-Nim游戲

總結

以上是生活随笔為你收集整理的第四章 数学知识【完结】的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。