楊皓丞
1天,2天,3天
這就是最以前唯一需要數字之處!
現在數學家如何定義正整數呢?
不可能,永遠定義不完
為正整數?
1. 1是正整數
2. 任一個正整數的“下一個數字”也是正整數
聽起來很唬爛吧?
1. \( 1 \in \mathbb{N} \)
2. \( x \in \mathbb{N} \Rightarrow s(x) \in \mathbb{N} \)
所以,\(1, s(1), s(s(1)), ... \) 都是正整數
為了方便書寫,
我們把s(1)記做2,s(s(1))記做3...
現在有正整數的定義了,對於正整數,最重要的莫過於加法了
(記得嗎,正整數是為了表示個數,而個數最重要的就是要能加起來)
如何定義加法呢?
1. \( 1 + x = s(x) \)
2. \( s(x)+ y = x + s(y) \)
\( s(s(1))+ s(s(1)) = s(1) + s(s(s(1))) \)
\( = 1 + s(s(s(s(1)))) = s(s(s(s(s(1))))) \)
也就是3+3=6
有加法了!
現在我知道鄰居送我兩隻羊後我會有幾隻羊了。接著呢?
家裡每個小孩要吃兩碗飯,媽媽晚上要煮幾碗飯的份量?
1. \( 1 \times x = x \)
2. \( s(x) \times y = y + x \times y \)
太棒了!有了加法和乘法幾乎就已經征服正整數了,次方運算也是正整數重要的運算,大家可以自己試著定義看看
整個整數域就是正整數再加上0和負整數而已,也不難定義
1. \( 0 \in \mathbb{Z} \)
2. \( x \in \mathbb{Z} \Rightarrow s(x) \in \mathbb{Z} \)
3. \( s(x) \in \mathbb{Z} \Rightarrow -s(x) \in \mathbb{Z} \)
整數的加法和乘法的定義也很類似,大家自己試試看!
當然,我很想繼續跟大家討論為何後來接著出現有理數,實數,複數,但整數的數論和應用就已經夠我們討論一整天了!
今天只會用到整數,其實很簡單吧XD
int not_prime[N]={0};
vector<int> prime;
void prime_sieve(){
not_prime[1]=1;
for(int i=2;i<N;i++){
for(int j=2;j<i;j++)
if(i%j==0)
not_prime[i]=1
if(!not_prime[i])
prime.push_back(i);
}
}
int not_prime[N]={0};
vector<int> prime;
void prime_sieve(){
not_prime[1]=1;
for(int i=2;i<N;i++){
if(!not_prime[i]){
prime.push_back(i);
for(int j=2;i*j<N;j++)
not_prime[i*j]=1;
}
}
}
int not_prime[N]={0};
vector<int> prime;
void prime_sieve(){
not_prime[1]=1;
for(int i=2;i<N;i++){
if(!not_prime[i]){
prime.push_back(i);
}
for(int j=0;j<prime.size()&&i*prime[j]<N;j++){
not_prime[i*prime[j]]=1;
if(i%prime[j]==0)
break;
}
}
}
int gcd(int p,int q){
if(q==0)return p;
return gcd(q,p%q);
}
a,b為給定兩數,
\(ax+by=1\)有整數解\( \Leftrightarrow gcd(a,b)=1\)
此定理可以推廣成
\(ax+by=m\)有整數解\( \Leftrightarrow gcd(a,b)|m\)
找整數解的方式,跟\(gcd\)差不多,用輾轉相除法!
int extgcd(int p,int q,int &x,int &y){
if(q==0){
x=1,y=0;
return p;
}
int ret=extgcd(q,p%q,y,x);
y-=(p/q)*x;
return ret;
}
void prime_sieve(){
//...
}
vector<PII> factorization(int N){
vector<PII> factors;
for(int i=0;i<prime.size()&&prime[i]<=N;i++){
int cnt=0;
while(N%prime[i]==0){
cnt++;
N/=prime[i];
}
if(cnt)
factors.push_back(make_pair(prime[i],cnt));
}
return factors;
}
void prime_sieve(){
//...
}
vector<PII> factorization(int N){
vector<PII> factors;
for(int i=0;i<prime.size()&&prime[i]<=sqrt(N);i++){
int cnt=0;
while(N%prime[i]==0){
cnt++;
N/=prime[i];
}
if(cnt)
factors.push_back(make_pair(prime[i],cnt));
}
if(N!=1)factors.push_back(make_pair(N,1));
return factors;
}
void prime_sieve(){
//...
}
vector<PII> factorization(int N){
vector<PII> factors;
while(N!=1){
int cnt=0,fac=first_prime_factor[N];
while(N%fac==0)
N/=fac,cnt++;
factors.push_back(make_pair(fac,cnt));
}
return factors;
}
哪些是二元運算?
哪些是群?
\[ab \equiv 1\; mod \; (m)\]
\[\Leftrightarrow ab=qm+1\]
\[\Leftrightarrow ab+(-q)m=1\]
根據裴蜀定理
\[\Leftrightarrow gcd(a,m)=1\]
可重複 | 不可重複 | |
---|---|---|
排列 | ||
組合 |
排列組合的答案通常很大,會要求模一個質數,後面都假設為\(Q\)!
還有以下範例程式都用int,但排列組合實做一定要用long long !
int power(int n,int m){
int num=n,ret=1;
while(m){
if(m%2)ret=ret*num%Q;
num=num*num%Q;
m/=2;
}
return ret;
}
int lad[MAX],inv_lad[MAX];
int power(int n,int m){}
int inv(int a){
return power(a,Q-2);
}
void preprocess(){
int i;
lad[0]=inv_lad[0]=1;
for(i=1;i<MAX;i++){
lad[i]=lad[i-1]*i%Q;
inv_lad[i]=inv_lad[i-1]*inv(i)%Q;
}
}
int C(int n,int m){
return lad[n]*inv_lad[m]%Q*inv_lad[n-m]%Q;
}
int lad[MAX],inv_lad[MAX],inv[MAX];
void preprocess(){
int i;
lad[0]=lad[1]=inv_lad[0]=inv_lad[1]=inv[1]=1;
for(i=1;i<MAX;i++){
lad[i]=lad[i-1]*i%Q;
inv[i]=(Q-Q/i)*inv[Q%i]%Q;
inv_lad[i]=inv_lad[i-1]*inv[i]%Q;
}
}
int C(int n,int m){
return lad[n]*inv_lad[m]%Q*inv_lad[n-m]%Q;
}