排列组合&数论
idy002老师的代码(day1)
#include<bits/stdc++.h>
const int N = 5000 + 10;
const int Mod = 1e9 + 7;
long long comb[N][N];
void init(int n) {
for(int i = 0; i <= n; i++) {
for(int j = 0; j <= i; j++) {
if(j == 0 || j == i)
comb[i][j] = 1;
else
comb[i][j] = (comb[i-1][j-1] + comb[i-1][j]) % Mod;
}
}
}
void print(int s) {
for(int i = 7; i >= 0; i--)
printf("%d", (s>>i)&1);
printf("\n");
}
void subset(int u) {
// int u = 0x5; // 0000 0101
for(int s = u; s; s = (s - 1) & u) {
print(s);
}
print(0);
}
int mpow(int a, int b, int m) {
int rt=1;
for(; b; b>>=1,a=(1LL*a*a)%m)
if(b&1) rt=(1LL*rt*a)%m;
return rt;
}
// a * b % m
long long mul(long long a, long long b, long long m) {
long long rt = 0;
for(; b; b>>=1,a=(a+a)%m)
if(b&1) rt=(rt+a)%m;
return rt;
}
// lucas
long long lucas(long long n, long long m, int p) {
if(n == 0 && m == 0) return 1;
if(n < m) return 0;
return lucas(n / p, m / p, p) * comb[n % p][m % p] % p;
}
// gcd
long long gcd(long long a, long long b) {
return b == 0 ? a : gcd(b, a % b);
}
void exgcd(long long a, long long b, long long &d, long long &x, long long &y) {
if(b == 0) {
d = a, x = 1, y = 0;
} else {
long long x0, y0;
exgcd(b, a % b, d, x0, y0);
// x0 * b + y0*(a - (a/b)*b) = d
// a * y0 + b * (x0 - (a/b)*y0) = d
x = y0;
y = x0 - (a / b) * y0;
}
}
const int Mod = 1e9 + 7;
struct Matrix {
int w[2][2];
void zero() {
for(int i = 0; i < 2; i++)
for(int j = 0; j < 2; j++)
w[i][j] = 0;
}
void unit() {
for(int i = 0; i < 2; i++)
for(int j = 0; j < 2; j++)
w[i][j] = (i == j);
}
int *operator[](int i) {
return w[i];
}
};
Matrix operator*(const Matrix &r, const Matrix &s) {
Matrix c;
for(int i = 0; i < 2; i++)
for(int j = 0; j < 2; j++) {
c[i][j] = 0;
for(int k = 0; k < 2; k++)
c[i][j] = (c[i][j] + 1LL * r[i][k] * s[k][j])% Mod;
}
return c;
}
Matrix mpow(Matrix a, int b) {
Matrix rt;
for(rt.unit(); b; b>>=1,a=a*a)
if(b & 1) rt=rt*a;
return rt;
}
int primes[33], ptot;
vector<pair<int,int> > split(int n) {
vector<pair<int,int> > stk;
for(int i = 2; i * i <= n; i++) {
if(n % i == 0) {
stk.push_back(make_pair(i, 0));
while(n % i == 0) {
n /= i;
stk.back().second++;
}
}
}
if(n != 1) {
stk.push_back(make_pair(n, 1));
}
return stk;
}
#include <vector>
#include <cstdio>
#include <algorithm>
using namespace std;
int countbits(int s) {
int rt = 0;
while(s) {
rt++;
s -= s & -s;
}
return rt;
}
int count(int m, int n) {
vector<int> stk;
for(int i = 2; i * i <= n; i++) {
if(n % i == 0) {
stk.push_back(i);
while(n % i == 0)
n /= i;
}
}
if(n != 1) stk.push_back(n);
if(stk.size() == 0) return 1;
int rt = 0;
int u = (1<<stk.size()) - 1;
for(int s = u; s; s = (s - 1) & u) {
int mul = 1;
for(int t = 0; t < (int)stk.size(); t++) {
if((s>>t) & 1) mul *= stk[t];
}
if(countbits(s) & 1)
rt += m / mul;
else
rt -= m / mul;
}
return m - rt;
}
int main() {
while(1) {
int m, n;
scanf("%d%d", &m, &n);
printf("%d\n", count(m,n));
}
}
我觉得他的这个 exgcd 实在不美观啊,我觉得不行并且搞了一套自己用的
long long X,Y,d;
void exgcd(long long a,long long b)
{
if(b==0){X=1;Y=0;d=a;}
else
{
exgcd(b,a%b);
long long t=X-a/b*Y;X=Y;Y=t;
}
}
学习内容
排列组合
二项式定理 及其推论
可重排列
循环排列
区分盒子,不区分球
卡特兰数列 递推式
容斥原理
Lucas
数论
最大公约数gcd && 最小公倍数lcm
二元一次不等式
欧拉函数
其实我大部分都没有搞懂,但还是先贴上来再说吧