前言:数论很难也很有意思,慢慢回顾和慢慢学,记录自己的感悟和理解。
keeping going !
欧拉函数:
假定phi(x)为x的欧拉函数,这个函数表示的就是1~i中和i互质的数。例phi(1) = 1,phi(2) = 1,phi(8) = 4。
欧拉函数的通式$phi(x) = x * prod_{x = 1}^{tot} (1-frac{1}{pi})$//tot为x的质因子的个数,注意是质因子。
那么我们对这个式子化简一下:$phi(x) = x * prod_{x = 1}^{tot} (frac{pi-1}{pi})$
那么就可以o(sqrt(n))得到一个数的欧拉函数。
代码思想:因为都是质因子,那么我们做质因子分解即可。
然后边分解边乘。
LL eular(LL x) { LL ans = x; int m = sqrt(x); for(rg int i = 2;i <= m;++i) { if(x%i == 0) { ans = ans/i*(i-1);//注意先除后乘,防止爆精度 while(x/i == 0) x /= i; } } if(x > 1) ans = ans/x*(x-1); return ans; }
欧拉函数求和通式:定义$s[i] = sum_{j = 1}^{i} phi[j]$
可由杜教筛得 $s[i] = frac{i*(i+1)}{2} - sum_{j = 2}^{i} s[frac{i}{j}]$
欧拉定理:
当满足a与m互质时,有$a^{b} mod (m) equiv a^{b mod phi[m]} mod (m)$
欧拉降幂:
由欧拉定理,我们可以得到欧拉降幂的公式。
显然用的条件是在次数过大时。次数小直接快速幂就可以了。
当$gcd(a,m) = 1 , a^{b} mod (m) equiv a^{bmod(phi[m])} mod (m)$
当$gcd(a,m) != 1 , b >= phi[m] , a^{b} mod (m) equiv a^{bmod(phi[m]) + phi[m]} mod (m)$
其他直接快速幂。
模板题:洛谷P5091 【模板】扩展欧拉定理
这里我们直接去判断b 是否 > 最大的模数就行。
LL eular(LL x) { LL ans = x,m = sqrt(x); for(rg LL i = 2;i <= m;++i) { if(x%i == 0) { ans = ans/i*(i-1); while(x%i == 0) x /= i; } } if(x > 1) ans = ans/x*(x-1); return ans; } LL quick_mi(LL a,LL b,LL p) { LL re = 1; while(b) { if(b&1) re = re*a%p; a = a*a%p; b >>= 1; } return re; } int main() { LL a;a = read(); LL m;m = read(); string s;cin >> s; int len = s.size(); LL ans; if(len <= 8) { LL ma = 0; for(rg int i = 0;i < len;++i) ma = ma*10+s[i]-'0'; ans = quick_mi(a,ma,m); } else { LL phi = eular(m),ma = 0; if(__gcd(a,m) == 1)//底数和模数互质 { for(rg int i = 0;i < len;++i) ma = (ma*10+s[i]-'0')%phi; ans = quick_mi(a,ma,m); } else { for(rg int i = 0;i < len;++i) ma = (ma*10+s[i]-'0')%phi; ans = quick_mi(a,ma+phi,m); } } printf("%lld ",ans); system("pause"); }
威尔逊定理:
当p为质数时有$(p-1)! equiv -1 mod(p)$
也可得$(p-2)! equiv 1 mod(p)$
即(p - 1)! mod p = p - 1
这里的变形推导没推出来。太菜了~
这里介绍下同余变换法则:
$a equiv b mod (m)$表示a-b可以整除m,也就是可以推得下面的第二个
$a equiv b mod (m) ightarrow (a+b) equiv 0 mod (m)$
$a equiv b mod (m) ightarrow (a-b) equiv 0 mod (m)$
$a equiv b mod (m) ightarrow a * c equiv b * c mod (m)$
$a equiv b mod (m) ightarrow a^{n} equiv b^{n} mod (m)$
多个式子:如果a ≡ x(mod d),b ≡ m(mod d),则
// Author: levil #include<bits/stdc++.h> using namespace std; typedef long long LL; typedef pair<string,int> pii; const int N = 1e6+5; const int M = 2e5+5; const LL Mod = 1e9+7; #define rg register #define pi acos(-1) #define INF 1e9 #define CT0 cin.tie(0),cout.tie(0) #define IO ios::sync_with_stdio(false) #define dbg(ax) cout << "now this num is " << ax << endl; namespace FASTIO{ inline LL read(){ LL x = 0,f = 1;char c = getchar(); while(c < '0' || c > '9'){if(c == '-') f = -1;c = getchar();} while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();} return x*f; } void print(int x){ if(x < 0){x = -x;putchar('-');} if(x > 9) print(x/10); putchar(x%10+'0'); } } using namespace FASTIO; void FRE(){/*freopen("data1.in","r",stdin); freopen("data1.out","w",stdout);*/} int f[N]; bool check(int x) { if(x < 2) return false; int m = sqrt(x); for(rg int i = 2;i <= m;++i) if(x%i == 0) return false; return true; } void init() { for(rg int i = 1;i < N;++i) { int x = 3*i+7; if(check(x)) f[i] = f[i-1]+1; else f[i] = f[i-1]+0; } } int main() { init(); int ca;ca = read(); while(ca--) { int n;n = read(); printf("%d ",f[n]); } system("pause"); }