一些关于中国剩余定理的数论题(POJ 2891/HDU 3579/HDU 1573/HDU 1930)

2891 -- Strange Way to Express Integers

 1 import java.math.BigInteger;
 2 import java.util.Scanner;
 3 
 4 public class Main {
 5     static final BigInteger ZERO = new BigInteger("0");
 6     static final BigInteger ONE = new BigInteger("1");
 7     static BigInteger gcd(BigInteger a, BigInteger b) {
 8         if (b.equals(ZERO)) return a;
 9         else return gcd(b, a.mod(b));
10     }
11     static BigInteger lcm(BigInteger a, BigInteger b) {
12         return a.divide(gcd(a, b)).multiply(b);
13     }
14     static void gcd(BigInteger a, BigInteger b, BigInteger p[]) {
15         if (b.equals(ZERO)) {
16             p[0] = a;
17             p[1] = new BigInteger("1");
18             p[2] = new BigInteger("0");
19         } else {
20             gcd(b, a.mod(b), p);
21             BigInteger tmp = p[1];
22             p[1] = p[2];
23             p[2] = tmp;
24             p[2] = p[2].subtract(a.divide(b).multiply(p[1]));
25         }
26     }
27     static BigInteger[] A = new BigInteger[11111];
28     static BigInteger[] R = new BigInteger[11111];
29     static BigInteger work(int n) {
30         BigInteger[] p = new BigInteger[3];
31         BigInteger a = A[0], r = R[0];
32         for (int i = 1; i < n; i++) {
33             BigInteger dr = R[i].subtract(r);
34             gcd(a, A[i], p);
35             if (dr.mod(p[0]).equals(ZERO) == false) return new BigInteger("-1");
36             BigInteger tmp = a.multiply(p[1]);
37             a = lcm(a, A[i]);
38             tmp = tmp.mod(a).add(a).mod(a);
39             tmp = tmp.multiply(dr).divide(p[0]).add(r);
40             r = tmp.mod(a).add(a).mod(a);
41         }
42         return r;
43     }
44     public static void main(String[] args) {
45         int n;
46         Scanner in = new Scanner(System.in);
47         while (in.hasNext()) {
48             n = in.nextInt();
49             String tmp;
50             for (int i = 0; i < n; i++) {
51                 tmp = in.next();
52                 A[i] = new BigInteger(tmp);
53                 tmp = in.next();
54                 R[i] = new BigInteger(tmp);
55             }
56             System.out.println(work(n).toString());
57         }
58     }
59 }
View Code

  因为懒得写大数,所以直接用java的大数类来做。用这个是因为,虽然输入输出不会超过64位整型,不过中间过程还是超了。

Problem - 3579

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <cmath>
 4 #include <algorithm>
 5 #include <cstring>
 6 
 7 using namespace std;
 8 
 9 typedef long long LL;
10 
11 const int N = 11;
12 LL A[N], R[N];
13 inline LL gcd(LL a, LL b) { return b ? gcd(b, a % b) : a;}
14 inline LL lcm(LL a, LL b) { return a / gcd(a, b) * b;} 
15 void gcd(LL a, LL b, LL &d, LL &x, LL &y) {
16     if (b) { gcd(b, a % b, d, y, x); y -= a / b * x;}
17     else { d = a, x = 1, y = 0;}
18 }
19 
20 LL work(int n) {
21     LL x, y, d, a = A[0], r = R[0];
22     for (int i = 1; i < n; i++) {
23         LL dr = R[i] - r;
24         gcd(a, A[i], d, x, y);
25         if (dr % d) return -1;
26         //cout << x << ' ' << y << ' ' << d << endl;
27         LL tmp = a * x;
28         a = lcm(a, A[i]);
29         tmp = (tmp % a + a) % a * dr / d + r;
30         r = (tmp % a + a) % a;
31         //cout << a << ' ' << r << ' ' << tmp << endl;
32     }
33     return r ? r : a;
34 }
35 
36 int main() {
37     int n, T, cas = 1;
38     cin >> T;
39     while (T-- && cin >> n) {
40         for (int i = 0; i < n; i++) cin >> A[i];
41         for (int i = 0; i < n; i++) cin >> R[i];
42         cout << "Case " << cas++ << ": " << work(n) << endl;
43     }
44     return 0;
45 }
View Code

Problem - 1573

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <cmath>
 4 #include <algorithm>
 5 #include <cstring>
 6 
 7 using namespace std;
 8 
 9 typedef long long LL;
10 inline LL gcd(LL a, LL b) { return b ? gcd(b, a % b) : a;}
11 inline LL lcm(LL a, LL b) { return a / gcd(a, b) * b;}
12 void gcd(LL a, LL b, LL &d, LL &x, LL &y) {
13     if (b) { gcd(b, a % b, d, y, x); y -= a / b * x;}
14     else d = a, x = 1, y = 0;
15 }
16 
17 LL A[11], R[11], LCM;
18 LL work(int n) {
19     LL d, x, y, a = A[0], r = R[0];
20     for (int i = 1; i < n; i++) {
21         LL dr = R[i] - r;
22         gcd(a, A[i], d, x, y);
23         //cout << d << ' ' << x << ' ' << y << endl;
24         if (dr % d) return -1;
25         LL tmp = a * x * dr / d + r;
26         a = lcm(a, A[i]);
27         r = (tmp % a + a) % a;
28         //cout << a << '~' << r << endl;
29     }
30     LCM = a;
31     return r ? r : a;
32 }
33 
34 int main() {
35     //freopen("in", "r", stdin);
36     int T, n;
37     LL r;
38     cin >> T;
39     while (cin >> r >> n) {
40         for (int i = 0; i < n; i++) cin >> A[i];
41         for (int i = 0; i < n; i++) cin >> R[i];
42         LL ans = work(n);
43         //cout << ans << ' ' << LCM << endl;
44         if (~ans) cout << max(0ll, (r - ans + LCM) / LCM) << endl;
45         else puts("0");
46     }
47 }
View Code

Problem - 1930

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <cmath>
 4 #include <algorithm>
 5 #include <cstring>
 6 
 7 using namespace std;
 8 
 9 typedef long long LL;
10 inline LL gcd(LL a, LL b) { return b ? gcd(b, a % b) : a;}
11 inline LL lcm(LL a, LL b) { return a / gcd(a, b) * b;}
12 void gcd(LL a, LL b, LL &d, LL &x, LL &y) {
13     if (b) { gcd(b, a % b, d, y, x); y -= a / b * x;}
14     else d = a, x = 1, y = 0;
15 }
16 
17 LL A[6], R[6];
18 
19 bool check(LL a) {
20     for (int i = 0; i < 3; i++) {
21         if (a % 100 > 27 || a % 100 <= 0) return false;
22         a /= 100;
23     }
24     return true;
25 }
26 
27 LL cal() {
28     LL d, x, y, a = A[0], r = R[0];
29     for (int i = 1; i < 4; i++) {
30         LL dr = R[i] - r;
31         gcd(a, A[i], d, x, y);
32         if (dr % d) {
33             puts("WTF??");
34             while (1) ;
35         }
36         LL tmp = a * x;
37         //a = lcm(a, A[i]);
38         a *= A[i];
39         tmp %= a;
40         tmp *= dr / d;
41         tmp += r;
42         r = (tmp % a + a) % a;
43         //cout << a << '~' << r << endl;
44     }
45     while (!check(r)) r += a;
46     //cout << r << ' ' << a << endl;
47     return r;
48 }
49 
50 LL cal(LL x) {
51     for (int i = 0; i < 4; i++) R[i] = x % 100, x /= 100;
52     //for (int i = 0; i < 4; i++) cout << A[i] << ' ' << R[i] << endl;
53     return cal();
54 }
55 
56 const LL ep[3] = { 10000, 100, 1};
57 char out[111111];
58 
59 int main() {
60     //freopen("in", "r", stdin);
61     int T, n, p;
62     LL tmp, x;
63     cin >> T;
64     while (T-- && cin >> n) {
65         p = 0;
66         for (int i = 0; i < 4; i++) cin >> A[i];
67         reverse(A, A + 4);
68         for (int i = 0; i < n; i++) {
69             cin >> tmp;
70             tmp = cal(tmp);
71             for (int i = 0; i < 3; i++) {
72                 x = tmp / ep[i] % 100;
73                 out[p++] = x == 27 ? ' ' : (x - 1 + 'A');
74             }
75         }
76         out[p] = 0;
77         while (p > 0 && out[p - 1] == ' ') out[--p] = 0;
78         puts(out);
79     }
80     return 0;
81 }
View Code

——written by Lyon

原文地址:https://www.cnblogs.com/LyonLys/p/2013_07_30_Lyon.html