洛谷 P3868 【猜数字】


思路:

由题意得$n$ $-$ $a[i]$ 整除 $b[i]$。

可以转化为$n$ $-$ $a[i]$ $=$ $b[i]$ $*$ $k$。

于是可得$n$ $-$ $a[i]$ $≡$ $0$ $(mod$ $b[i])$。

即$n$ $≡$ $a[i]$ $(mod$ $b[i])$。

因为题目中说$b[i]$两两互质,显而易见这是个裸的中国剩余定理。

这个题数据有点大,会爆$long$ $long$,所以将代码中的乘法改成这个就行了。

ll mul(ll a, ll b, ll m) {return (a * b - (ll)((long double)a * b / m) * m + m) % m;}

$code:$

 1 #include <bits/stdc++.h>
 2 #define INF 0x3f3f3f3f
 3 #define ll long long
 4 using namespace std;
 5 ll n, ans, sum, M[110], x, y, t[110], m[110], a[110];
 6 ll mul(ll a, ll b, ll m) {return (a * b - (ll)((long double)a * b / m) * m + m) % m;}
 7 void exgcd(ll a, ll b, ll &x, ll &y)
 8 {
 9     if(!b) x = 1, y = 0;
10     else exgcd(b, a % b, y, x), y -= x * (a / b);
11     return;
12 }
13 int main()
14 {
15     scanf("%lld", &n);
16     sum = 1;
17     for(int i = 1; i <= n; ++i) scanf("%lld", &a[i]);
18     for(int i = 1; i <= n; ++i) scanf("%lld", &m[i]), sum *= m[i];
19     for(int i = 1; i <= n; ++i) M[i] = sum / m[i];
20     for(int i = 1; i <= n; ++i) exgcd(M[i], m[i], x, y), t[i] = (x % m[i] + m[i]) % m[i];
21     for(int i = 1; i <= n; ++i) ans += mul(mul(a[i], t[i], sum), M[i], sum);
22     printf("%lld", (ans % sum + sum) % sum);
23     return 0;
24 }

原文地址:https://www.cnblogs.com/qqq1112/p/13491344.html