一些关于中国剩余定理的数论题(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 }
因为懒得写大数,所以直接用java的大数类来做。用这个是因为,虽然输入输出不会超过64位整型,不过中间过程还是超了。
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 }
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 }
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 }
——written by Lyon