NOIP2018模板總結(dalao自動忽略)【數學】
阿新 • • 發佈:2018-12-17
質因數分解
//質因數分解 int prime[MAXN], tim[MAXN], cnt; void Divide(int N) { printf("%d = ", N); for(int i = 2; i * i <= N; i++) if(N % i == 0) { prime[++cnt] = i; while(N % i == 0) N /= i, tim[cnt]++; } if(N > 1) prime[++cnt] = N, tim[cnt] = 1; printf("%d^%d", prime[1], tim[1]); for(int i = 2; i <= cnt; i++) printf(" * %d^%d", prime[i], tim[i]); }
線性篩素數/尤拉函式
線性篩素數/尤拉函式 int phi[MAXN], prime[MAXP], cnt; bool vis[MAXN]; void Prime(int N) { phi[1] = 1; for(int i = 2; i <= N; i++) { if(!vis[i]) prime[++cnt] = i, phi[i] = i-1; for(int j = 1; j <= cnt && i*prime[j] <= N; j++) { vis[i*prime[j]] = true; if(i % prime[j] == 0) { phi[i*prime[j]] = phi[i] * prime[j]; break; } phi[i*prime[j]] = phi[i] * (prime[j]-1); } } }
Miller-Robin大素數測試/快速冪/快速乘
//Miller-Robin大素數測試 #define LL long long //O(1)快速乘(模) LL kmul(LL a,LL b,LL P) { a = (a % P + P) % P,b = (b % P + P) % P; return ((a * b - (LL)((long double)a / P * b + 1e-6) * P) % P + P) % P; } //O(logn)快速冪 LL kpow(LL a, LL b, LL mod) { LL ret = 1; while(b) { if(b & 1) ret = kmul(ret, a, mod); a = kmul(a, a, mod); b >>= 1; } return ret; } bool Mil_Rb(LL N, LL a) { LL d = N-1; int s = 0; while(!(d & 1)) d >>= 1, s++; LL t = kpow(a, d, N); if(t == 1 || t == -1) return true; for(int i = 0; i < s; i++) { if(t == N-1) return 1; t = kmul(t, t, N); } return 0; } bool isPrime(LL N) { if(N == 2) return true; if(N == 1 || !(N & 1)) return false; LL a[5] = { 2, 3, 5, 7, 11 }; for(int i = 0; i < 5; i++) { if(N == a[i]) return true; if(!(N % a[i])) return false; if(N > a[i] && !Mil_Rb(N, a[i])) return false; } return true; }
gcd & lcm
//gcd & lcm
LL gcd(LL a, LL b) { return b ? gcd(b, a%b) : a; }
LL lcm(LL a, LL b) { return a / gcd(a, b) * b; }
exgcd
//a*x + b*y = b*y + (a%b)*x + (a/b)*b*x
// = b*(y+x*(a/b)) + (a%b)*x
#define LL long long
void exgcd(LL a, LL b, LL &x, LL &y, LL &gcd)
{
if(!b) { x = 1, y = 0; gcd = a; return; }
exgcd(b, a%b, y, x, gcd); y -= x * (a/b);
}
中國剩餘定理
//中國剩餘定理
void exgcd(int a, int b, int &x, int &y)
{
if(!b) { x = 1; y = 0; return; }
exgcd(b, a%b, y, x); y -= x*(a/b);
}
int CRT(int *W, int *B, int k) // W > B
{
int x, y, mulsum = 1, ans = 0;
for(int i = 1; i <= k; i++)
mulsum *= W[i];
for(int i = 1; i <= k; i++)
{
int M = mulsum/W[i];
exgcd(W[i], M, x, y);
ans = (ans + y*M*B[i]) % mulsum;
}
if(ans < 0) ans += mulsum;
return ans;
}
卡特蘭數 // ksm(a, mod-2)在mod為素數的情況下≡a^(-1),即a在mod下的逆元
//Catalan
const int MAXN = 5005;
int Catalan[MAXN];
int pre()
{
Catalan[0] = 1;
for(int i = 1; i < MAXN; i++)
for(int j = 0; j < i; j++)
Catalan[i] = (Catalan[i] + (LL)Catalan[j] * Catalan[i-j-1] %mod) % mod;
// or
for(int i = 1; i < MAXN; i++)
Catalan[i] = (LL)Catalan[i-1] * (4*i-2) % mod * ksm(n+1, mod-2);
}
int Catalan(int n)
{
return C(n<<1, n) * ksm(n+1, mod-2);
// or
return (C(n<<1, n) - C(n<<1, n-1)) % mod + mod) % mod;
}