质数
试除法判定质数
#include <iostream>
#include <algorithm>
using namespace std;
bool is_prime(int x)
{
if (x < 2) return false;
for (int i = 2; i <= x / i; i ++ )
if (x % i == 0)
return false;
return true;
}
int main()
{
int n;
cin >> n;
while (n -- )
{
int x;
cin >> x;
if (is_prime(x)) cout << "Yes" << endl;
else cout << "No" << endl;;
}
return 0;
}
分解质因数
#include <iostream>
#include <algorithm>
using namespace std;
void divide(int x)
{
for (int i = 2; i <= x / i; i ++ )
{
if (x % i == 0)
{
int s = 0;
while (x % i == 0) x /= i, s ++ ;
cout << i << ' ' << s << endl;
}
}
if (x > 1) cout << x << ' ' << 1 << endl;
cout << endl;
}
int main()
{
int n;
cin >> n;
while (n -- )
{
int x;
cin >> x;
divide(x);
}
return 0;
}
筛质数
#include <iostream>
#include <algorithm>
using namespace std;
const int N= 1000010;
int primes[N], cnt;
bool st[N];
void get_primes(int n)
{
for (int i = 2; i <= n; i ++ )
{
if (!st[i]) primes[cnt ++ ] = i;
for (int j = 0; primes[j] <= n / i; j ++ )
{
st[primes[j] * i] = true;
if (i % primes[j] == 0) break;
}
}
}
int main()
{
int n;
cin >> n;
get_primes(n);
cout << cnt << endl;
return 0;
}
约数
试除法求约数
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
int T;
cin >> T;
while(T--)
{
int n;
cin >> n;
vector<int> res;
for(int i = 1; i <= n /i; i++)
{
if(n % i == 0)
{
res.push_back(i);
if(n / i != i)
res.push_back(n / i);
}
}
sort(res.begin(), res.end());
for(auto x : res) cout << x << " ";
cout << endl;
}
}
约数个数
#include <iostream>
#include <algorithm>
#include <unordered_map>
using namespace std;
const int mod = 1e9+7 ;
int main()
{
int T;
cin >> T;
unordered_map<int, int> h;
while(T--)
{
int n;
cin >> n;
for(int i = 2; i <= n / i; i++)
{
while(n % i == 0)
{
h[i] ++;
n = n / i;
}
}
if(n > 1) h[n]++;
}
long long res = 1;
for(auto iter = h.begin(); iter != h.end(); iter++)
{
res = res * (iter->second + 1) % mod ;
}
cout << res;
}
约数之和
#include <iostream>
#include <algorithm>
#include <unordered_map>
#include <vector>
using namespace std;
typedef long long LL;
const int N = 110, mod = 1e9 + 7;
int main()
{
int n;
cin >> n;
unordered_map<int, int> primes;
while (n -- )
{
int x;
cin >> x;
for (int i = 2; i <= x / i; i ++ )
{
while (x % i == 0)
{
x /= i;
primes[i] ++ ;
}
}
if (x > 1) primes[x] ++ ;
}
LL res = 1;
for (auto p : primes)
{
LL a = p.first, b = p.second;
LL t = 1;
while (b -- ) t = (t * a + 1) % mod;
res = res * t % mod;
}
cout << res << endl;
return 0;
}
最大公约数
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int T;
cin >> T;
while(T--)
{
int a, b;
cin >> a >> b;
while(b)
{
int c = a % b;
a = b;
b = c;
}
cout << a << endl;
}
}
欧拉函数
欧拉函数
#include <iostream>
using namespace std;
int phi(int x)
{
int res = x;
for (int i = 2; i <= x / i; i ++ )
if (x % i == 0)
{
res = res / i * (i - 1);
while (x % i == 0) x /= i;
}
if (x > 1) res = res / x * (x - 1);
return res;
}
int main()
{
int n;
cin >> n;
while (n -- )
{
int x;
cin >> x;
cout << phi(x) << endl;
}
return 0;
}
筛法求欧拉函数
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N = 1000010;
int primes[N], cnt;
int phi[N];
bool st[N];
void get_eulers(int n)
{
phi[1] = 1;
for (int i = 2; i <= n; i++)
{
if (!st[i])
{
primes[cnt++] = i;
phi[i] = i - 1;
}
for (int j = 0; primes[j] <= n / i; j++)
{
st[primes[j] * i] = true;
if (i % primes[j] == 0)
{
phi[primes[j] * i] = phi[i] * primes[j];
break;
}
phi[primes[j] * i] = phi[i] * (primes[j] - 1);
}
}
}
int main()
{
int n;
cin >> n;
get_eulers(n);
LL res = 0;
for (int i = 1; i <= n; i++) res += phi[i];
printf("%lld\n", res);
return 0;
}
快速幂
快速幂
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
LL quick(LL a,LL b,LL p)
{
LL res=1;
while(b>0)
{
if(b&1) res=a*res%p;
a=a*a%p;
b>>=1;
}
return res;
}
int main()
{
int n;
scanf("%d", &n);
for (int i = 0; i < n; i ++ )
{
int a,b,p;
scanf("%d%d%d", &a, &b,&p);
printf("%d\n",quick(a,b,p));
}
}
快速幂求逆元
#include <iostream>
using namespace std;
typedef long long LL;
LL qmi(int a, int b, int p)
{
LL res = 1;
while(b){
if(b & 1) res = res * a % p;
a = (LL)a * a % p;
b >>= 1;
}
return res;
}
int main()
{
int n; cin >> n;
while(n --){
int a, p;
cin >> a >> p;
if(a % p == 0) puts("impossible");
else cout << qmi(a, p - 2, p) << endl;
}
return 0;
}
扩展欧几里得算法
扩展欧几里得算法
#include<bits/stdc++.h>
using namespace std;
int exgcd(int a, int b, int &x, int &y){
if(b==0){
x = 1, y = 0;
return a;
}
int x1,y1,gcd;
gcd = exgcd(b, a%b, x1, y1);
x = y1, y = x1 - a/b*y1;
return gcd;
}
int main(){
int n,a,b,x,y;
cin>>n;
while(n--){
cin>>a>>b;
exgcd(a,b,x,y);
cout<<x<<" "<<y<<endl;
}
return 0;
}
线性同余方程
#include<bits/stdc++.h>
using namespace std;
using LL = long long ;
int exgcd(int a, int b, int &x, int &y){
if(b==0){
x = 1, y = 0;
return a;
}
int x1,y1,gcd;
gcd = exgcd(b, a%b, x1, y1);
x = y1, y = x1 - a/b*y1;
return gcd;
}
int main(){
int n,a,b,x,y,m;
cin>>n;
while(n--){
cin>>a>>b>>m;
int d=exgcd(a,m,x,y);
if (b % d) puts("impossible");
else
{
x = (LL)x * b / d % m;
cout << x << endl;
}
}
return 0;
}
中国剩余定理
表达整数的奇怪方式
#include <cstdio>
#include <iostream>
using namespace std;
typedef long long LL;
int n;
LL exgcd(LL a, LL b, LL &x, LL &y){
if(b == 0){
x = 1, y = 0;
return a;
}
LL d = exgcd(b, a % b, y, x);
y -= a / b * x;
return d;
}
LL inline mod(LL a, LL b){
return ((a % b) + b) % b;
}
int main(){
scanf("%d", &n);
LL a1, m1;
scanf("%lld%lld", &a1, &m1);
for(int i = 1; i < n; i++){
LL a2, m2, k1, k2;
scanf("%lld%lld", &a2, &m2);
LL d = exgcd(a1, -a2, k1, k2);
if((m2 - m1) % d){ puts("-1"); return 0; }
k1 = mod(k1 * (m2 - m1) / d, abs(a2 / d));
m1 = k1 * a1 + m1;
a1 = abs(a1 / d * a2);
}
printf("%lld\n", m1);
return 0;
}
高斯消元
高斯消元解线性方程组
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
const int N = 110;
const double eps = 1e-6;
int n;
double a[N][N];
int gauss()
{
int c, r;
for (c = 0, r = 0; c < n; c ++ )
{
int t = r;
for (int i = r; i < n; i ++ )
if (fabs(a[i][c]) > fabs(a[t][c]))
t = i;
if (fabs(a[t][c]) < eps) continue;
for (int i = c; i < n + 1; i ++ ) swap(a[t][i], a[r][i]);
for (int i = n; i >= c; i -- ) a[r][i] /= a[r][c];
for (int i = r + 1; i < n; i ++ )
if (fabs(a[i][c]) > eps)
for (int j = n; j >= c; j -- )
a[i][j] -= a[r][j] * a[i][c];
r ++ ;
}
if (r < n)
{
for (int i = r; i < n; i ++ )
if (fabs(a[i][n]) > eps)
return 2;
return 1;
}
for (int i = n - 1; i >= 0; i -- )
for (int j = i + 1; j < n; j ++ )
a[i][n] -= a[j][n] * a[i][j];
return 0;
}
int main()
{
cin >> n;
for (int i = 0; i < n; i ++ )
for (int j = 0; j < n + 1; j ++ )
cin >> a[i][j];
int t = gauss();
if (t == 0)
{
for (int i = 0; i < n; i ++ ) printf("%.2lf\n", a[i][n]);
}
else if (t == 1) puts("Infinite group solutions");
else puts("No solution");
return 0;
}
高斯消元解异或线性方程组
#include <iostream>
using namespace std;
const int N = 110;
int a[N][N];
int n;
int gauss()
{
int r, c;
for (r = 0, c = 0; c < n; c++) {
int t = r;
for (int i = r; i < n; i++)
if (a[i][c]) {
t = i;
break;
}
if (a[t][c] == 0) continue;
for (int i = c; i <= n; i++) swap(a[r][i], a[t][i]);
for (int i = r + 1; i < n; i++) {
if (a[i][c]) {
for (int j = c; j <= n; j++)
a[i][j] ^= a[r][j];
}
}
r++;
}
if (r < n) {
for (int i = r; i < n; i++)
if (a[i][n])
return 2;
return 1;
} else {
for (int i = n - 1; i >= 0; i--) {
for (int j = i + 1; j < n; j++) {
a[i][n] ^= a[i][j] * a[j][n];
}
}
return 0;
}
}
int main()
{
cin >> n;
for (int i = 0; i < n; i++)
for (int j = 0; j <= n; j++)
cin >> a[i][j];
int res = gauss();
if (res == 0) {
for (int i = 0; i < n; i++)
cout << a[i][n] << endl;
} else if (res == 1)
cout << "Multiple sets of solutions"<< endl;
else
cout << "No solution" << endl;
}
求组合数
求组合数I
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 2010, mod = 1e9 + 7;
int c[N][N];
void init()
{
for (int i = 0; i < N; i ++ )
for (int j = 0; j <= i; j ++ )
if (!j) c[i][j] = 1;
else c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]) % mod;
}
int main()
{
int n;
init();
scanf("%d", &n);
while (n -- )
{
int a, b;
scanf("%d%d", &a, &b);
printf("%d\n", c[a][b]);
}
return 0;
}