數學相關總結
質因數分解
inline void divide(int n){
for(register int i=2;i*i<=n;++i){
if(n%i==0){
p[++len]=i;c[len]=0;
while(n%i==0)n/=i,++c[len];
}
}
if(n>1)p[++len]=n,c[len]=1;
}
線性篩質數
inline void find(void){ memset(v,true,sizeof(v));v[1]=false; for(register int i=2;i<=n;++i){ if(v[i]){primes[++priN]=i;} for(register int j=1;j<=priN;++j){ if(i*primes[j]>n)break; v[i*primes[j]]=false; if(i%primes[j]==0)break; } } }
N的正約數個數
\((1+c_1)\times (1+c_2)\times ...\times (1+c_m)\)
N的正約數之和
\((1+p_1+p_1^2+...+p_1^{c_1})\times (1+p_2+p_2^2+...+p_2^{c_2})\times ...\times (1+p_m+p_m^2+...+p_m^{c_m})\).
更相減損術
\(gcd(a,b)=gcd(b,a-b)=gcd(a,a-b)\).
歐幾里得演算法
\(gcd(a,b)=gcd(b,a\mod b)\).
尤拉函式
\(\varphi (N)=N\times \frac{p_1}{p_1-1}\times \frac{p_2}{p_2-1}\times ...\times \frac{p_m}{p_m-1}\)
inline void get(void){//n log n 篩尤拉函式
for(register int i=2;i<=n;++i)phi[i]=i;
for(register int i=2;i<=n;++i){
if(phi[i]==i){
for(register int j=i;j<=n;++j){
phi[j]=phi[j]*i/(i-1);
}
}
}
}
擴充套件歐幾里得演算法
inline int exgcd(int a,int b,int &x,int &y){ if(b==0){x=1;y=0;return a;} int d=exgcd(b,a%b,x,y); int z=x;x=y;y=z-y*(a/b); return d; }
ax+by=c方程通解
設\(d=gcd(a,b)\)。
如果\(d|c\),則方程有解,反之無解。
通解為\(x=\frac{c}{d}\times x_0+\frac{b}{c}\times k\). \(y=\frac{c}{d}\times y_0+\frac{a}{c}\times k\).
附:整數域上的三分(求最大值)
int l=-1e9,r=1e9;
while(r-l>10){
int lmid=((l+r)>>1)-3,rmid=((l+r)>>1)+3;
if(f(lmid)<f(rmid))l=lmid;
else r=rmid;
}
int ans=-1e9;
for(register int i=l;i<=r;++i){
ans=max(ans,f(i));
}
乘法逆元
即給定a,p,求一個整數x,使得\(ax\equiv1(\mod p)\)
1. 費馬小定理(p是質數)
因為\(a^{p-1}\equiv1(\mod p)\)
所以\(a \times a^{p-2}\equiv 1(\mod p)\)
2. exgcd(a、p互質)
\(a x\equiv 1(\mod p)\)
\(\Leftrightarrow ax=1+py\)
\(\Leftrightarrow ax-py=1\)
$\Leftrightarrow $exgcd(a,p,x,y)
OK.
一個小誤區
負數取模。
例如我們要計算\(-10\mod 3\),在數學界規定\(-10\mod 3=2\),即\((-10)\div 3=-4......2\),而在C++語言中\(-10\% 3=-1\),所以我們為了求出正確答案,應該ans=(a%p+p)%p
,這樣算出來就是\(2\)了。
所以凡是有可能出現負數的情況,都要這樣取模,或者直接:
inline int mod(int a,int p){
return (a%p+p)%p;
}
直接呼叫即可。
擴充套件中國剩餘定理
其實想通了很簡單。
假設我們已經求出了方程組前\(k-1\)個方程的解x,現在要求第\(k\)個方程的解。
記\(m=lcm(m_1,m_2,...,m_{k-1})\),則\(x+i\times m\)同樣是前\(k-1\)個方程的解。
再來看第\(k\)個方程,我們無非就是求一個整數\(t\),使得\(x+t\times m\equiv b_k(\mod m_k)\)。
搞清楚未知數是t,已知數是\(x,m,b_k,m_k\)。
這不就是exgcd?(線性同餘方程)
求出新的解\(x'=x+t\times m\),繼續做即可。
組合數
符號:(從n個數中選m個)\(C_m^n\)
定義式:\(C_n^m=\frac{n!}{m!(n-m)!}\)。
遞推式:\(C_n^m=C_{n-1}^{m-1}+C_{n-1}^m\)。
性質:\(C_n^m=C_{n}^{n-m}\)。
卡特蘭數列:\(Cat_n=\frac{C_{2n}^n}{n+1}\)。
高斯消元法
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#define LL long long
#define FILEIN(s) freopen(s".in","r",stdin)
#define FILEOUT(s) freopen(s".out","w",stdout)
#define FILE(s) FILEIN(s);FILEOUT(s)
#define mem(s,v) memset(s,v,sizeof(s))
using namespace std;
template<class Type>
inline Type read(void){
Type x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return f*x;
}
const int maxn=105;
int n;double a[maxn][maxn],x[maxn];
#define eps 1e-7
inline bool gause(void){
for(register int i=1;i<=n;++i){//列舉行
int k=i;
for(register int j=i+1;j<=n;++j){//列舉行
if(fabs(a[k][i])<fabs(a[j][i]))k=j;
}
if(fabs(a[k][i])<eps)return false;
for(register int j=i;j<=n+1;++j){//列舉列
swap(a[i][j],a[k][j]);
}
double Tmp=a[i][i];
for(register int j=i;j<=n+1;++j){//列舉列
a[i][j]/=Tmp;
}
for(register int j=1;j<=n;++j){//列舉行
if(j==i)continue;
double tmp=a[j][i];
for(register int k=i;k<=n+1;++k){//列舉列
a[j][k]-=a[i][k]*tmp;
}
}
}
for(register int i=1;i<=n;++i)x[i]=a[i][n+1];
return true;
}
int main(){
n=read<int>();
for(register int i=1;i<=n;++i){
for(register int j=1;j<=n+1;++j){
a[i][j]=read<int>();
}
}
if(!gause()){
puts("No Solution");return 0;
}
for(register int i=1;i<=n;++i)printf("%.2lf\n",x[i]);
return 0;
}