1. 程式人生 > >NOIP前 基礎數學模板

NOIP前 基礎數學模板

  • 最大公因數&最小公倍數( g c d l c m gcd,lcm
  • 乘法逆元(三種方法)
  • 快速乘&快速冪
  • 線性篩-素數&最大質因數&最小質因數&尤拉函式
  • 擴充套件歐幾里得
  • 質因數分解
  • 組合數
  • 高斯消元
  • 矩陣快速冪
  • 康拓展開
最大公約數&最小公倍數
inline int gcd(int x,int y){
	int z=x%y;
	while(z){x=y;y=z;z=x%y;}
	return y;
}
inline int lcm(int x,int y){
	return x/gcd(x,y)*y;//(先除後乘,不然容易爆int)
}

當然在求gcd的時候你也可以不用手寫,可以直接呼叫stl的庫__gcd()


乘法逆元

存在a的逆元:當且僅當 g c d ( a , p )

= 1 gcd(a,p)=1 (p為模數)(可以用擴充套件歐幾里得來證明)
逆元的作用:模意義下的除法,可以不炸精度

1.線性遞推

  • 線性遞推只在a<=p的時候有用!!!
    因為對於大於p的數,這個就毫無意義了(仔細想一下推導的過程,不清楚可以再問哦)
  • 對模數沒有特殊要求,但要注意資料範圍是否支援O(n)
  • 仔細看一下資料範圍
    (這道題是保證了 n &lt; p n&lt;p ,所以可以使用線性遞推)
inv[1]=1;
for(int i=2;i<=n;++i)
	inv[i]=(p-p/i)*1ll*inv[p%i]%p;//注意乘long long

2.擴充套件歐幾里得
將式子轉化為 a x + p y = 1 ax+py=1
x x 就是a在模p意義下的逆元(調整 x 到0~m-1的範圍中即可)
這種演算法效率較高,常數較小,時間複雜度為O(ln n)
基本上適用於求所有擬元

inline void exgcd(int a,int b,int &x,int &y){
	if(!b){x=1;y=0;return;}
	exgcd(b,a%b,y,x);
	y-=a/b*x;
}
exgcd(a,p,x,y);
x=(x%p+p)%p;

3.費馬小定理
模數為質數的時候: a p 1 1 ( m o d p ) a^{p-1}\equiv1(mod p)
即可知: a a p 2 1 ( m o d p ) a*a^{p-2}\equiv1(mod p)
然後直接快速冪


快速乘&快速冪

快速乘

ll ksc(ll a,ll b,ll p){
	ll res=0;
	while(b){
		if(b&1) res=(res+a)%p;
		a=(a+a)%p;
		b>>=1;
	}
	return res;
}

快速冪

ll ksm(ll a,ll b,ll p){
	ll res=1;
	while(b){
		if(b&1) res=ksc(res,a,p);
		a=ksc(a,a,p);
		b>>=1;
	}
	return res;
}

線性篩

pri 是素數集,mx是最大質因數,mn 是最小質因數,phi 是尤拉函式,mark 是標記一個數是否為素數(是的話,mark=0)
特別的,phi[1]=1

inline void linear_sieves(){
	mark[1]=1;phi[1]=1;
	for(int i=2;i<=N;++i){
		if(!mark[i]){pri[++num]=i;mn[i]=i;mx[i]=i;phi[i]=i-1;}
		for(int j=1;j<=num&&pri[j]*i<=N;++j){
			int now=pri[j]*i;
			mark[now]=1;
			mn[now]=pri[j];mx[now]=mx[i];
			if(i%pri[j]==0){
				phi[now]=phi[i]*pri[j];
				break;
			}
			else phi[now]=phi[i]*(pri[j]-1);
		}
	}
}

擴充套件歐幾里得

對於任意的兩個數x,y,求 a x + b y = g c d ( a , b ) ax+by=gcd(a,b) 的解
擴充套件到更一般的情況,求 a x + b y = c ax+by=c 也是可以的
但這個式子有解當且僅當 g c d ( a , b ) c gcd(a,b)|c

(平時我們用的調整,只在gcd(a,b)==1的時候適用,所以不管怎麼樣,全部先除以gcd(a,b),然後該怎麼搞就怎麼搞)

void exgcd(ll a,ll b,ll &x,ll &y){
	if(!b){
		x=1;y=0;return;
	}
	exgcd(b,a%b,y,x);
	y-=a/b*x;
}

質因數分解

一個數大於 x \sqrt{x} 的質因數最多隻有一個
所以篩到 x \sqrt{x} 就夠了

inline void divide(int x){
	for(int i=1;i<=num&&pri[i]*pri[i]<=x;++i){
		while(x%pri[i]==0){
			x/=pri[i];
			cnt[pri[i]]++;
		}
	}
	if(x!=1) cnt[x]++;
}

組合數

組合數的一般求解公式:
C n m = n ! ( n m ) ! m ! C_n^m=\frac{n!}{(n-m)!*m!}
組合數必備三條公式:
C n m = C n m 1 C_n^m=C_n^{m-1}
C n m = C n 1 m 1 + C n 1 m C_n^m=C_{n-1}^{m-1}+C_{n-1}^{m}
C n 0 + C n 1 + C n 2 + C n 3 . . . + C n n = 2 n C_n^0+C_n^1+C_n^2+C_n^3...+C_n^n=2^n

常見求解方法:
1.楊輝三角形

	for(int i=0;i<2000;++i) c[i][0]=c[i][i]=1;
	for(int i=1;i<2000;++i)
		for(int j=1;j<i;++j)
			c[i][j]=(c[i-1][j]+c[i-1][j-1])%;

2.線性篩出階乘和逆元,O(1) 求組合數
fac 是階乘,ifac 是階乘的逆元

inline void init(){
	fac[0]=1;
	for(int i=1;i<=n;++i) fac[i]=(fac[i-1]*1ll*i)%P;
	ifac[n]=ksm(fac[n],P-2);
	for(int i=n-1;i>=1;--i) ifac[i]=ifac[i+1]*1ll*(i+1)%P;
}
inline ll C(ll n,ll m){	return fac[n]*1ll*ifac[n-m]%P*ifac[m]%P;}

高斯消元

如果無解就返回-1
無窮解返回0
有解返回1,並輸出一組解

inline int gauss(){
	int i,j,k;
	for(i=1;i<=n;++i){
		k=i;
		for(j=i
            
           

相關推薦

NOIP 基礎數學模板

最大公因數&最小公倍數( g c d

NOIP 基礎字串模板

雜湊(字串的常規處理) KMP(字串匹配) Manacher(最長迴文子串) Trie樹(用處可多了。) 雜湊 char st[2000]; map<ULL,bool> M; inli

NOIP 基礎演算法模板

二分(單調性) 三分(單峰函式) 離散化 (資料範圍過大) 中位數 O(n) 逆序對(歸併排序&樹狀陣列) 矩陣字首和 二分 (整數域上的二分) int l=1,r=1000,ans=0; while(l<=r){

NOIP 基礎動態規劃模板

揹包問題 0/1揹包,完全揹包,多重揹包,分組揹包,二維揹包,混合揹包 最長上升子序列(LIS) 最長公共子序列(LCS) 最長公共上升子序列(?) 揹包 0/1揹包 (每個物品只能選擇一個) fo

C++語言基礎(18)-模板

ava col andro ted 獲取 聲明 精簡 androi int Java中的泛型編程可以極大的提升編程的效率,比如在android中查找一個控件的ID:標準寫法為: TextView tv_text = (TextView)findViewById(R.i

[日常] NOIP集訓日記

鏈表 然而 tex text style 數組 比較 ext spa 寫點流水賬放松身心... 10.8 前一天考完NHEEE的一調考試終於可以開始集訓了Orz (然後上來考試就遲到5min, GG) T1維護隊列瞎貪心, 過了大樣例交上去一點也不穩...T出翔只拿

【寫在NOIP

寧可 註意 代碼 多看 不能 考試 感覺 之前 日常 快NOIP了,感覺自己得總結一下吧。 1.要自信啊,相信自己啊,我明明還是有些實力的是吧。 哪怕之前被教練怎麽懟,自己別放棄啊 一定要註意心態吧,考試的時候怎麽都不能慌,你不會的題也不會有多少人會做的,你覺得難寫的題別人

Flask基礎(二)---模板渲染中的過濾器定義

模板渲染 過濾器 Flask中模板渲染中過濾器的定義: from flask import Flask,render_template app = Flask(__name__) @app.route("/") def index(): return render_template("te

[總結] NOIP 的考試記錄

mes tdi val cas lin 寫在前面 down show latex 寫在前面 由於我天天被虐,模擬考還老是考的極差,感覺有必要開個博客記錄一下每場考試 由於懶得加美元符所以這篇博客不用 latex 由於要弄代碼折疊我還特意換掉了 Markdown 編輯器

Vue學習計劃(基礎二)-模板語法,計算屬性,偵聽器

形式 否則 偵聽器 響應 lib family align code set 模板語法、計算屬性和偵聽器 目標: 1、熟練使用vue的模板語法 2、理解計算屬性與偵聽器的用法以及應用場景 1. 模板語法 <div id="app"> <!-- 以

POJ - 1330 Nearest Common Ancestors 最近公共祖先+鏈式向星 模板

mon represent pac different add const nod sam ger A rooted tree is a well-known data structure in computer science and engineering. An ex

素數篩 + 綴和 模板

namespace 模板 color efi bits return pos space sin 素數篩 + 前綴和 模板 1 #include <bits/stdc++.h> 2 #define ll long long int 3 #defi

寫給NOIP的自己

天才 差距 開機 就會 也不會 希望 clas 得到 有時 深夜發騷 半年沒上文化課了,像樣的句子也整不出來幾句,然而人有時就是會矯情。 學OI也有一年了,坦白說,我剛開始接觸這個的時候純粹是好玩,並沒有指望自己能學出來個什麽,就像學了7年美術啥也不會,學了9年象棋照樣

NOIP計劃

tarjan 時間 kmp noip 靠譜 系列 回路 真的 不出 距離NOIp還有13天 距離繼續學/退役還有13天 是時候列一波計劃了 1. 要學的東西 cdq分治(突然發現cdq分治不太行,而且說不定可以用來代替想不出來的數據結構題) 主席樹(寫的太少啦,不熟練) 啟

$Noip$的小總結哦

有用 舞臺 輕松 noip line lin 發揮 分配 優秀 考試失誤點與積累 有點不知道該幹嘛了,狀態有點差,寫點東西。(後面可能會加更一點東西?) 常規錯誤 \(1.\) 數組開小 \(2.\) \(int\)和\(longlong\) \(3.\) 開某題時間太久

NOIP的一些計劃

一些想法 距離NOIP2018只剩下一個星期的時間了,通過這幾天在長郡的考試,漸漸感覺還有好多東西自己還不夠熟練,也有些東西到現在還不會,現將NOIP前的一些計劃列在這裡,爭取在考前把他們全部完成 一些模板 這裡是NOIP可能會考的資料結構和演算法的模板 字串演算法: \(kmp\) \(mana

noip提高組字串模板[trie樹,kmp]

遇到字串最好是hash靈活處理 但有些東西還是要學 //trie樹 void build(string s){ int p=0; for(int i=0;i<=s.length();i++){ if(trie[p].son[s[i]-'a']==0) trie[p].s

Noip的大抱佛腳----圖論

圖論 知識點 Tarjan相關 邊雙和點雙/割邊和割點 強連通分量:有向圖中任意兩個頂點都有相互到達的路徑的一個極大子圖 邊雙連通分量:一個子圖中刪去任意一條邊都不影響圖的連通性 點雙連通分量:一個子圖中刪去任意一個點都不影響圖的連通性 割邊:連線兩個邊雙的邊 割點:連線兩個點雙的點 程式碼如下:

Noip的大抱佛腳----資料結構

資料結構 線段樹 注意:空間開4倍 神奇標記 From8.26 Test_zsy(CPU監控) 如果一個點權為\(val\)的點被打上了\((a,b)\)標記,那麼他的實際點權為\(max(a+val,b)\) 幹啥滴? 標記不下放 區間加標記不下放,維護區間max或者最大值 方法

Noip的大抱佛腳----根號對數演算法

根號演算法 分塊 數列分塊入門九題(hzwer) 入門題1,2,3,4,5,7 問題:給一段區間打上標記後單點查詢 解法:主要是每塊維護一些標記,計算答案等,此類分塊較為簡單 注意:塊大小一般為\(\sqrt n\) 複雜度:\(O(n\sqrt n)\) 入門題6 問題