【經常使用算法總結——中國剩餘定理】

中國剩餘定理,又稱孫子定理(什麼名字啊)是中國古代求解一次同餘式組(見同餘)的方法。是數論中一個重要定理。首先來一個小!例!題!吧!c++

註釋:三數爲a b c,餘數分別爲 m1 m2 m3,%爲求  今年 餘計算,&&是「且」運算。 1、分別找出能被兩個數整除,而知足被第三個整除餘一的最小的數。 k1%b==k1%c==0 && k1%a==1; k2%a==k2%c==0 && k2%b==1; k3%a==k3%b==0 && k3%c==1; 2、將三個未知數乘對應數字的餘數再加起來,減去這三個數的最小公倍數的整數倍即得結果。 Answer = k1×m1 + k2×m2 + k3×m3 - P×(a×b×c); P爲知足Answer > 0的最大整數; 或者 Answer = (k1×m1 + k2×m2 + k3×m3)%(a×b×c) ;

咱們來小小的證實一波spa

 

 設M=m1*m2*......*mn   Mi=M/mi   設Mi的逆元爲Mi^(-1)(mod mi)   有Mi*Mi^(-1)≡1(mod mi)   ai*Mi*Mi^(-1)≡ai(mod mi)   對於全部的j不等於i   ai*Mi*Mi^(-1)≡0(mod mj)   因此答案就是全部ai*Mi*Mi^(-1)(mod p)的值

P3868 [TJOI2009]猜數字code

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 long long x,y;
 4 long long a[15],b[15];
 5 long long n;
 6 void exgcd(long long A,long long B)
 7 {
 8     if(B==0)
 9     {
10         x=1;
11         y=0;
12         return;
13     }
14     exgcd(B,A%B);
15     long long z=x;
16     x=y;
17     y=z-(A/B)*y;
18 }
19 long long fast(long long a1,long long b1,long long mod)
20 {
21     long long ans=0;
22     a1%=mod;
23     b1%=mod;
24     while(b1)
25     {
26         if(b1&1)
27         {
28             ans=(ans+a1)%mod;
29         }
30         b1>>=1;
31         a1=(a1+a1)%mod;
32     }
33     return ans;
34 }
35 long long china()
36 {
37     long long ans=0;
38     long long M=1;
39     for(long long i=1;i<=n;i++)
40         M*=b[i];
41     for(long long i=1;i<=n;i++)
42     {
43         long long m=M/b[i];
44         exgcd(m,b[i]);
45         while(x<0)
46             x+=b[i]; 
47         x%=b[i];
48         ans=(ans+fast(x,fast(m,(a[i]+M)%M,M),M)+M)%M;
49     }
50     return ans;
51 }
52 int main()
53 {
54     cin>>n;
55     for(long long i=1;i<=n;i++)
56     {
57         scanf("%lld",&a[i]);
58     }
59     for(long long i=1;i<=n;i++)
60     {
61         scanf("%lld",&b[i]);
62     }
63     cout<<china();
64     return 0;
65 }
相關文章
相關標籤/搜索