@Dmaxiya
2020-08-24T16:41:14.000000Z
字数 3846
阅读 1106
Hello_World
扩展欧几里得要解决的就是求解 整数解的问题。
首先证明:若方程有整数解,则 必然为 的整数倍。
设 ,则 ,又因为 都是整数,所以 必然是 的整数倍。
进而求解:方程 的整数解。
比较系数可得:,当 时,,此时 即为方程 的解。
所以可以得出 代码如下:
#define LL long longLL exgcd(LL a, LL b, LL &x, LL &y) {if(b == 0) {x = 1;y = 0;return a;}LL gcd = exgcd(a, b, x, y);LL tmp = x;x = y;y = tmp - a / b * y;return gcd;}
还可以通过判断 是否是返回值 的倍数,来计算 的解:
LL cal(LL a, LL b, LL c) {LL x, y;LL gcd = exgcd(a, b, x, y);if(c % gcd != 0) {return -1;}LL MOD = abs(b / gcd);return (x % MOD + MOD) % MOD;}
该函数的功能是计算方程 的 的最小非负整数解,若无解,则返回 。注意这里 的下一个整数解为 ,而不是 ,读者请自行证明。
要得到 的解,且 为最小非负整数解,则 函数也可以写为:
bool cal(LL a, LL b, LL c, LL &x, LL &y) {LL gcd = exgcd(a, b, x, y);if(c % gcd != 0) {return false;}LL MOD = abs(b / gcd);x = (x % MOD + MOD) % MOD;y = (c - a * x) / b;return true;}
一个数字 可能可以由几个连续的素数相加得到,给定 ,求有几种连续的素数和为 。
素数打表,然后对素数做前缀和, 枚举起点,对于每个起点二分查找终点。
#include <iostream>#include <cstdio>#include <cstdlib>#include <cmath>#include <climits>#include <cstring>#include <string>#include <vector>#include <list>#include <queue>#include <stack>#include <map>#include <set>#include <bitset>#include <algorithm>#include <functional>#include <iomanip>using namespace std;#define LL long longconst int maxn = 10000 + 100;int n;bool vis[maxn];int prime[maxn];int sum[maxn];int *it;void Prime(int n) {for(LL i = 2; i < n; ++i) {if(!vis[i]) {prime[++prime[0]] = i;}for(int j = 1; j <= prime[0] && i * prime[j] < n; ++j) {int k = i * prime[j];vis[k] = true;if(i % prime[j] == 0) {break;}}}for(int i = 1; i <= prime[0]; ++i) {sum[i] = sum[i - 1] + prime[i];}}int main() {#ifdef LOCALfreopen("test.txt", "r", stdin);// freopen("out.txt", "w", stdout);#endif // LOCALios::sync_with_stdio(false);Prime(maxn);while(scanf("%d", &n), n != 0) {int ans = 0;for(int i = 0; i == 0 || prime[i] < n; ++i) {it = lower_bound(sum, sum + prime[0] + 1, sum[i] + n);if(*it == sum[i] + n) {++ans;}}printf("%d\n", ans);}return 0;}
给定 ,计算 的最小非负整数解,若无解则输出“”。
裸题。
#include <iostream>#include <cstdio>#include <cstdlib>#include <cmath>#include <climits>#include <cstring>#include <string>#include <vector>#include <list>#include <queue>#include <stack>#include <map>#include <set>#include <bitset>#include <algorithm>#include <functional>#include <iomanip>using namespace std;#define LL long longLL a, b;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, x, y);LL tmp = x;x = y;y = tmp - a / b * y;return d;}LL cal(LL a, LL b, LL c) {LL x, y;LL gcd = exgcd(a, b, x, y);if(gcd != 1) {return INT_MIN;}b = abs(b);return (x % b + b) % b;}int main() {#ifdef LOCALfreopen("test.txt", "r", stdin);// freopen("out.txt", "w", stdout);#endif // LOCALios::sync_with_stdio(false);while(scanf("%lld%lld", &a, &b) != EOF) {LL ans = cal(a, b, 1);if(ans == INT_MIN) {printf("sorry\n");} else {printf("%lld %lld\n", ans, (1 - a * ans) / b);}}return 0;}
有 组数据,每组数据有 组 值,计算 的值。
快速幂裸题。
#include <iostream>#include <cstdio>#include <cstdlib>#include <cmath>#include <climits>#include <cstring>#include <string>#include <vector>#include <list>#include <queue>#include <stack>#include <map>#include <set>#include <bitset>#include <algorithm>#include <functional>#include <iomanip>using namespace std;#define LL long longint T, n;LL MOD, a, b, ans;LL fast_pow(LL res, LL n) {LL ans;for(ans = 1; n != 0; n >>= 1) {if((n & 1) == 1) {ans = (ans * res) % MOD;}res = (res * res) % MOD;}return ans;}int main() {#ifdef LOCALfreopen("test.txt", "r", stdin);// freopen("out.txt", "w", stdout);#endif // LOCALios::sync_with_stdio(false);scanf("%d", &T);while(T--) {ans = 0;scanf("%lld%d", &MOD, &n);for(int i = 0; i < n; ++i) {scanf("%lld%lld", &a, &b);ans += fast_pow(a, b);ans %= MOD;}printf("%lld\n", ans);}return 0;}