/*
* 同时得到欧拉函数和素数表
*/
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 10000000;
bool check[MAXN + 10];
int phi[MAXN + 10];
int prime[MAXN + 10];
int tot; // 素数个数
void phi_and_prime_table(int N)
{
memset(check, false, sizeof(check));
phi[1] = 1;
tot = 0;
for (int i = 2; i <= N; i++)
{
if (!check[i])
{
prime[tot++] = i;
phi[i] = i - 1;
}
for (int j = 0; j < tot; j++)
{
if (i * prime[j] > N)
{
break;
}
check[i * prime[j]] = true;
if (i % prime[j] == 0)
{
phi[i * prime[j]] = phi[i] * prime[j];
break;
}
else
{
phi[i * prime[j]] = phi[i] * (prime[j] - 1);
}
}
}
}
快速GCD
int kgcd(int a, int b)
{
if (a == 0)
{
return b;
}
if (b == 0)
{
return a;
}
if (!(a & 1) && !(b & 1))
{
return kgcd(a >> 1, b >> 1) << 1;
}
else if (!(b & 1))
{
return kgcd(a, b >> 1);
}
else if (!(a & 1))
{
return kgcd(a >> 1, b);
}
else
{
return kgcd(abs(a - b), min(a, b));
}
}
扩展GCD
/*
* 求x,y使得gcd(a, b) = a * x + b * y;
*/
int extgcd(int a, int b, int &x, int &y)
{
if (b == 0)
{
x = 1;
y = 0;
return a;
}
int d = extgcd(b, a % b, x, y);
int t = x;
x = y;
y = t - a / b * y;
return d;
}
素数表
/*
* 素数筛选,查找出⼩小于等于MAXN的素数
* prime[0]存素数的个数
*/
const int MAXN = 100000;
int prime[MAXN + 1];
void getPrime()
{
memset(prime, 0, sizeof(prime));
for (int i = 2; i <= MAXN; i++)
{
if (!prime[i])
{
prime[++prime[0]] = i;
}
for (int j = 1; j <= prime[0] && prime[j] <= MAXN / i; j++)
{
prime[prime[j] * i] = 1;
if (i % prime[j] == 0)
{
break;
}
}
}
}
矩阵
/*
* 矩阵乘法 n*n矩阵乘法
*/
#define MAXN 111
#define mod(x) ((x) % MOD)
#define MOD 1000000007
#define LL long long
int n;
struct mat
{
int m[MAXN][MAXN];
};
// 矩阵乘法
mat operator * (mat a, mat b)
{
mat ret;
LL x;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
x = 0;
for (int k = 0; k < n; k++)
{
x += mod((LL)a.m[i][k] * b.m[k][j]);
}
ret.m[i][j] = mod(x);
}
}
return ret;
}