数论
知识总结
快速幂
long long binpow(long long a, long long b, long long m) {
a %= m;
long long res = 1;
while (b > 0) {
if (b & 1) res = res * a % m;
a = a * a % m;
b >>= 1;
}
return res;
}
素数判定
暴力做法
米勒罗宾判定
- 费马小定理
- 二次探测定理
bool millerRabbin(int n) {
if (n < 3) return n == 2;
int a = n - 1, b = 0;
while (a % 2 == 0) a /= 2, ++b;
// test_time 为测试次数,建议设为不小于 8
// 的整数以保证正确率,但也不宜过大,否则会影响效率
for (int i = 1, j; i <= test_time; ++i) {
int x = rand() % (n - 2) + 2, v = quickPow(x, a, n);
if (v == 1 || v == n - 1) continue;
for (j = 0; j < b; ++j) {
v = (long long)v * v % n;
if (v == n - 1) break;
}
if (j >= b) return 0;
}
return 1;
}
最大公约数
int gcd(int a, int b) {
return b == 0 ? a : gcd(b, a % b);
}
拓展欧几里得
void exgcd(int a, int b, int& x, int& y) {
if (b == 0) {
x = 1, y = 0;
return;
}
exgcd(b, a % b, y, x);
y -= a / b * x;
}
素数筛法
欧拉筛法
const int maxn = 50005;
int prime[maxn] , visit[maxn] , vis[1000005];
void Prime(){
memset (prime, 0 , sizeof (prime));
memset (visit, 1 , sizeof (visit));
visit[1] = 0;
for(int i = 2; i <= maxn; i++) {
if(visit[i])
prime[++prime[0]] = i;
for(int j = 1; j <= prime[0] && i*prime[j] <= maxn; j++) {
visit[i*prime[j]] = 0;
if(i % prime[j] == 0) {
break;
}
}
}
}
乘法逆元
费马小定理
逆元x为a^(b-2) mod b a是元,b是模数
int ksm(long long a, int b) {
int ans = 1;
a = (a % p + p) % p;
for (; b; b >>= 1) {
if (b & 1) ans = (a * ans) % p;
a = (a * a) % p;
}
return ans;
}
线性同余方程
int exgcd(int a, int b, int& x, int& y) {
if (b == 0) {
x = 1, y = 0;
return a;
}
int g = exgcd(b, a % b, y, x);
y -= a / b * x;
return g;
}
bool liEu(int a, int b, int c, int& x, int& y) {
int d = exgcd(a, b, x, y);
if (c % d != 0) return 0;
int k = c / d;
x *= k;
y *= k;
return 1;
}
质因数分解
list<int> breakdown (int N) {
list<int> result;
for (int i = 2; i * i <= N; i++) {
if (N % i == 0) {
while (N % i == 0) N /= i;
result.push_back(i);
}
}
if (N != 1)
result.push_back(N)
return result;
}
题解
题目
For a given positive integer n denote its k-rounding as the minimum positive integer x, such that x ends with k or more zeros in base 10 and is divisible by n.
For example, 4-rounding of 375 is 375·80 = 30000. 30000 is the minimum integer such that it ends with 4 or more zeros and is divisible by 375.
Write a program that will perform the k-rounding of n.
input
The only line contains two integers n and k (1 ≤ n ≤ 1e9, 0 ≤ k ≤ 8).
output
Print the k-rounding of n.
样例
input
375 4
output
30000
input
10000 1
output
10000
input
38101 0
output
38101
input
123456789 8
output
12345678900000000
思路
求n的倍数中有k个零的最小数 即lcm(n,10^k) 故直接快速幂与最大公约数即可求得
代码
#include <iostream>
using namespace std;
typedef long long ll;
ll gcd (ll a , ll b) {
return a % b ? gcd (b , a % b) : b;
}
ll ksm (ll a , ll b) {
ll res = 1;
while (b > 0) {
if (b & 1) res = res * a;
a = a * a;
b >>= 1;
}
return res;
}
int main () {
ll n , k , p;
cin >> n >> k;
p = ksm (10 , k);
cout << n * p / gcd (n , p);
return 0;
}
题目
Fedya studies in a gymnasium. Fedya’s maths hometask is to calculate the following expression:
(1^n + 2^n + 3^n + 4^n) mod 5
for given value of n. Fedya managed to complete the task. Can you? Note that given number n can be extremely large (e.g. it can exceed any integer type of your programming language).
input
The single line contains a single integer n (0 ≤ n ≤ 10105). The number doesn’t contain any leading zeroes.
output
Print the k-rounding of n.
样例
input
4
output
4
input
124356983594583453458888889
output
0
思路
打表找规律后可知每4个一个循环 若是4的倍数则是4 否则为0
代码
#include <iostream>
#include <cstring>
using namespace std;
typedef long long ll;
int main () {
string a;
cin >> a;
ll len = a.length() , num;
if (len >= 2) {
num = (a[len-2]-'0') * 10 + (a[len-1]-'0');
} else {
num = a[len-1]-'0';
}
if (num % 4) cout << 0;
else cout << 4;
return 0;
}