P3868 [TJOI2009]猜數字
阿新 • • 發佈:2018-10-04
printf max [1] tps else return 代碼 uid mat
中國剩余定理的模板題。
雖然說是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\n", excrt()); return 0; }
P3868 [TJOI2009]猜數字