P3868 [TJOI2009]猜数字
Posted garen-wang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P3868 [TJOI2009]猜数字相关的知识,希望对你有一定的参考价值。
中国剩余定理的模板题。
虽然说是CRT的模板,但是我不会CRT啊。我只会EXCRT
思路很清晰,都写在注释里面了。不懂的话看看我前面写过的一篇模板题的随笔。
PS:很荣幸能够帮到@niiick大佬。我帮大佬指正了一个小学生才纠结的东西。。。
代码:
#include<cstdio>
#include<cmath>
const int maxn = 15;
#define ll long long
ll a[maxn], b[maxn], n;
ll exgcd(ll a, ll b, ll &x, ll &y)
{
if(b == 0){ x = 1; y = 0; return a; }
else
{
ll ret = exgcd(b, a % b, x, y);
ll t = x;
x = y;
y = t - a / b * y;
return ret;
}
}
ll excrt()
{
ll ans = a[1], M = b[1];
for(int i = 2; i <= n; i++)
{
// ans + k * M
// ans + t * M === a[i] (mod b[i])
// t * M === a[i] - ans (mod b[i])
// t * M - yy * b[i] = a[i] - ans
// solve it through x * M - y * b[i] = gcd(M, b[i])
// t : x = a[i] - ans : gcd(M, b[i])
// t - bg = t - b[i] / gcd(M, b[i])
// upd
ll A = M, B = b[i], C = ((a[i] - ans) % b[i] + b[i]) % b[i];
ll x, y;
ll g = exgcd(A, B, x, y);
if(C % g != 0) return -1;
ll bg = B / g;
x = x * C / g % b[i];
x = (x + bg) % bg + bg;
ans += x * M;
M *= bg;
ans = (ans % M + M) % M;
}
return (ans % M + M) % M;
}
int main()
{
// b_i | (n - a_i)
// n - a_i % b_i = 0
// n - a_i === 0 (mod b_i)
// n === a_i (mod b_i)
scanf("%lld", &n);
for(int i = 1; i <= n; i++) scanf("%lld", &a[i]);
for(int i = 1; i <= n; i++) scanf("%lld", &b[i]);
printf("%lld
", excrt());
return 0;
}
以上是关于P3868 [TJOI2009]猜数字的主要内容,如果未能解决你的问题,请参考以下文章