标签:
http://acm.hdu.edu.cn/showproblem.php?pid=5768
1 #include <cstdio> 2 #include <algorithm> 3 #include <iostream> 4 #include <cstring> 5 #include <queue> 6 #include <cmath> 7 using namespace std; 8 typedef long long LL; 9 #define N 20 10 11 LL p[N], a[N]; 12 int bit[N]; 13 int n; 14 15 LL mul(LL a, LL b, LL m) 16 { 17 //快速乘法 18 LL ans = 0; 19 while(b) { 20 if(b & 1) ans = (ans + a) % m; 21 a <<= 1; 22 a %= m; 23 b >>= 1; 24 } 25 return ans; 26 } 27 28 LL exgcd(LL a, LL b, LL &x, LL &y) 29 { 30 if(b == 0) { 31 x = 1; 32 y = 0; 33 return a; 34 } 35 LL r = exgcd(b, a%b, x, y); 36 int t = x; 37 x = y; 38 y = t - a / b * y; 39 return r; 40 } 41 42 LL CRT(LL x, LL y) 43 { 44 //中国剩余定理: 找同时满足多个同余式的解 45 LL M = 1, ans = 0; 46 for(int i = 0; i <= n; i++) { 47 if(bit[i]) M *= p[i]; 48 } 49 for(int i = 0; i <= n; i++) { 50 if(bit[i]) { 51 LL x, y, Mi; 52 Mi = M / p[i]; 53 exgcd(Mi, p[i], x, y); 54 x = (x % p[i] + p[i]) % p[i]; 55 ans = (ans + mul(Mi * a[i] % M, x, M) % M + M) % M; 56 //ans找出来的是在 M 以内的特解即最小正整数解 57 } 58 } 59 //每过 M 可以有一个解 60 LL res = (y - ans + M) / M - (x - 1 - ans + M) / M; 61 return res; 62 } 63 64 void solve(LL x, LL y) 65 { 66 bit[n] = 1; 67 LL ans = 0; 68 int all = 1 << n; 69 for(int i = 0; i < all; i++) { 70 int tmp = i, k = 0; 71 for(int j = 0; j < n; j++) { 72 bit[j] = tmp & 1; 73 tmp >>= 1; 74 k += bit[j]; 75 } 76 k = k & 1 ? -1 : 1; 77 //k是计算包含多少个同余式 78 //容斥原理: 奇数减,偶数加,具体可以看《组合数学》P108 79 //计算出不具有性质(满足任意一个同余式)的数的数量 80 ans += CRT(x, y) * k; 81 } 82 printf("%I64d\n", ans); 83 } 84 85 int main() 86 { 87 int t; 88 scanf("%d", &t); 89 for(int cas = 1; cas <= t; cas++) { 90 LL x, y; 91 scanf("%d%I64d%I64d", &n, &x, &y); 92 for(int i = 0; i < n; i++) 93 scanf("%I64d%I64d", &p[i], &a[i]); 94 p[n] = 7, a[n] = 0; 95 printf("Case #%d: ", cas); 96 solve(x, y); 97 } 98 return 0; 99 }
HDU 5768:Lucky7(中国剩余定理 + 容斥原理)
标签:
原文地址:http://www.cnblogs.com/fightfordream/p/5773905.html