중국 잉여 정리 (CRT)

또한, 중국 잉여 정리로 알려진 중국 잉여 정리,

 

당신은 문제를 해결할 수 있습니까?

문제 :

항목의 무리

3/3 이분 왼쪽

5 3 5 점 남음

7 7 2 포인트 좌측

이 문서에서는 많은 요청

 

중국 잉여 정리는 다음과 같은 간단한 선형 합동 방정식을 제공합니다 :
중국 잉여 정리 (1)
 
중국 잉여 정리 : 정수 가정 m이 . 1, m 2, ..., m의 n 형 페어 질량 후 어떤 정수 : . 1 2, ..., N-,
 식 (S)
용액 및 일반 용액을 수득하는 방식으로 구성 될 수있다 :
설정
  중국 잉여 정리 (2)
의 정수이고, m은 . 1, m 2, ..., m의 n 형 제품 제공된
  중국 잉여 정리 (3)
이 부가되어 m 의 I보다 N- 정수의 곱 -.
설정
  중국 잉여 정리 (4)
이것의 역수
  중국 잉여 정리 (5) 
형태의 일반적인 솔루션
  중국 잉여 정리 (6) 
모듈로 M, 식 (S) 하나만 용액 감각 :
  중국 잉여 정리 (7)
 
 
M1, M2, ..., 미네소타 페어 품질이 만나고 해결해야합니다
1 LL의 반전 (LL의 t, LL의 P) {    // t关于P的逆元
2      LL X, Y, D;
(3)      D = ex_gcd (t, P, X, Y);
(4)      만약 (d ==의 1 ) {
 5           (X % 포인트의 + P) % P;
6      } 다른 
7          반환 - 1 ;
8  }
 9  
10  
11  // N个方程: X = A [i]는 (MOD m [I]) (0 <= i가 N <) 
12  
13 LL 중국 ( INT의 N, LL * A, LL의 *의 m) {
 14      LL M = 1 , RET = 0 ;
(15)     위한 ( int로 I = 0 ; I <N은, 내가 ++ ) {
 16          M * = m의 [I];
17      }
 18       ( int로 I = 0 ; I <N은, 내가 ++ ) {
 19          LL w = M / m [I];
20          RET = (RET INV + (w m [I]) * A [I] w) %의 M;
21      }
 22      리턴 (RET의 +의 M) %의 M;
23 }

 

그러나 그들은 우리가 그것을 수행하는 방법에있는 선형 방정식의 상대적으로 소수 모드가 아닌 경우?

 

문제에 대한 설명 : 주어진 양방향, NI 값 및 N1, N2, N3, ..., NI하지 않는 매 2 해상도의 평가 사이에 반드시 상호 국무? 
해결 방법 : 식을 병합의 연습을 사용합니다. 
여기서 두 번째 식은 설명한 제 예 병합 것이다 
: 도면 줄의 처음 두 방정식에서를 (단, K1은 K2 일부 정수)
 
 
 

1,573 X 다음 문제 코드 []이 부여 된 HDU 예 
에 http : // acm.hdu.edu.cn/showproblem.php?pid=1573 

 

 1 #include <iostream>
 2 #include <algorithm>
 3 
 4 typedef long long LL;
 5 
 6 using namespace std;
 7 
 8 int N;
 9 
10 
11 LL ex_gcd(LL a,LL b,LL &x,LL &y){
12     if (b == 0){
13         x = 1;
14         y = 0;
15         return a;
16     }
17     LL gcd = ex_gcd(b,a%b,y,x);
18     y -= (a/b)*x;
19     return gcd;
20 }
21 
22 LL inv(LL t,LL p){   // t 关于 p 的逆元
23     LL x,y,d;
24     d = ex_gcd(t,p,x,y);
25     if (d == 1){
26         return (x%p+p)%p;
27     }else
28         return -1;
29 }
30 
31 
32 // n个方程: x = a[i](mod m[i])   (0<=i<n)
33 
34 LL china(int n,LL *a,LL *m){
35     LL M = 1,ret = 0;
36     for (int i=0;i<n;i++){
37         M *= m[i];
38     }
39     for (int i=0;i<n;i++){
40         LL w = M/m[i];
41         ret = (ret + inv(w,m[i]) * w * a[i]) % M;
42     }
43     return (ret + M) % M;
44 }
45 
46 LL CRT(LL b[],LL n[],int num){
47     bool flag = false;
48     LL n1 = n[0],n2,b1 = b[0],b2,bb,d,t,k,x,y;
49     for (int i=1;i<num;i++){
50         n2 = n[i],b2 = b[i];
51         bb = b2 - b1;
52         d = ex_gcd(n1,n2,x,y);
53         if (bb%d){
54             flag = true;
55             break;
56         }
57         k = bb / d * x;
58         t = n2 / d;
59         if (t<0)
60             t = -t;
61         k = (k % t + t) % t;
62         b1 = b1 + n1 * k;
63         n1 = n1 / d * n2;
64     }
65     if (flag)     //无解
66         return 0;
67     if (b1 == 0)   // 如果解为0,题目要求正整数解,显然不可以
68         b1 = n1;   // n1为所以n[i] 的最小公倍数
69     if (b1>N)
70         return 0;
71     return (N-b1) / n1 + 1;      //形成的解:b1, b1+n1, b1+2n1,..., b1+xni...
72 }
73 
74 
75 int main(){
76     int t,num;
77     LL b[10],n[10];
78     scanf("%d",&t);
79     while (t--){
80         scanf("%d%d",&N,&num);
81         위한 ( int로 I = 0 ; I는 <NUM; 나는 ++ ) {
 82              는 scanf ( " %의 LLD " , 및 N []);
83          }
 84           ( int로 I = 0 ; I는 <NUM; 내가 ++ ) {
 85              는 scanf ( " %의 LLD " , B [I]);
86          }
 87          의 printf ( " % LLD \ 없음 " , CRT (B, N, NUM));
88      }
 89      반환  0 ;
90 }

 


 

추천

출처www.cnblogs.com/-Ackerman/p/11352769.html