辗转相除法(欧几里得算法)
作用 求最大公约数(gcd)
int gcd(int a, int b){
if(b == 0) return a;
return gcd(b, a % b)
}
扩展欧几里得算法
素数判定
bool isPrime(int n){
for(int i = 2; i * i <= n; i++){
if(n % i == 0) return false;
}
return n != 1;
}
埃式筛选(求n以内素数个数)
int prime[MAX_N]
bool isPrime[MAX_N + 1];
int sieve(int n){
int p = 0; //素数个数
for(int i = 0; i <= n; i++) isPrime[i] = true;
isPrime[0] = isPrime[1] = false;
for(int i = 2; i <= n; i++){
if(isPrime[i]){
prime[p++] = i;
for(int j = 2 * i; j <= n; j += i){
isPrime[j] = false;
}
}
}
}
区间筛法(挑战程序设计竞赛p120)
模运算
- (a + b) % p = (a % p + b % p) % p
- (a - b) % p = (a % p - b % p) % p
- (a * b) % p = (a % p * b % p) % p
- 除法不行
- (a^b) % p = ((a % p)^b) % p
结合率:
- ((a+b) % p + c) % p = (a + (b+c) % p) % p
- ((ab) % p * c)% p = (a * (bc) % p) % p
交换率:
- (a + b) % p = (b+a) % p
- (a * b) % p = (b * a) % p
分配率:
- ((a +b)% p * c) % p = ((a * c) % p + (b * c) % p) % p
快速幂
typedef long long ll;
ll mod ;
ll qpow(ll a, ll b) {
ll res = 1;
ll base = a;
while (b != 0) {
if (b & 1) res = res * a % mod;
base = base * base % mod
b >>= 1;
}
return res;
}
快速乘
typedef long long ll;
ll mod ;
ll qmul(ll a, ll b){
ll res = 0;
while(b != 0){
if(b & 1) res = (res + a) % mod;
a = (a + a) % mod;
n >>= 1;
}
}
矩阵快速幂
typedef long long ll;
int mod = 1e9 + 7;
//矩阵乘法
vector<vector<ll>> mul(const vector<vector<ll>>& a, const vector<vector<ll>>& b)
{
vector<vector<ll>> ans(a.size(), vector<ll>(b[0].size(), 0));
for (int i = 0; i < a.size(); ++i)
{
for (int j = 0; j < b[0].size(); ++j)
{
for (int k = 0; k < b.size(); ++k)
{
ans[i][j] += a[i][k] * b[k][j];
ans[i][j] %= mod;
}
}
}
return ans;
}
//矩阵a的n次方
vector<vector<ll>> power(vector<vector<ll>> a, int n)
{
vector<vector<ll>> ans(a.size(), vector<ll>(a.size(), 0));
for (int i = 0; i < a.size(); ++i)
{
ans[i][i] = 1;
}//单位阵
while (n != 0)
{
if (n & 1)
{
ans = mul(ans, a);
}
a = mul(a, a);
n >>= 1;
}
return ans;
}
- 题目:552 1137(感觉好像要根据状态机找出矩阵,然后才能算,之后看看)