Off more cattle tenth school field D Han Xin and His Troops Chinese remainder theorem

Meaning of the questions:

Han has a number of soldiers, given you a number of modulus and remainder, give you a range of restrictions within a 1e18, solving the congruence equations, if no solution, output "He must be lying," if the minimum solution is out of range limit the output "he may be lying," or the minimum output solution

NOTE: Not guaranteed modulus are relatively prime, does not guarantee "that he might be lying," the situation is not the answer to long long burst

answer:

Because they do not guarantee the prime modulus, we need to be solved with excrt.

False algorithm: excrt board to translate into python, and then a look of autistic Geological Survey program

n=0
m=0
bi=[]
ai=[]

def ggcd(_m,_n):
    if _n == 0:
        _x = 1
        _y = 0
        return _m,_x
    _a1 = _b = 1
    _a = _b1 = 0
    _c = _m
    _d = _n
    _q = int(_c//_d)
    _r = _c%_d
    while _r:
        _c = _d
        _d = _r
        _t = _a1
        _a1 = _a
        _a = _t-_q*_a
        _t = _b1
        _b1 = _b
        _b = _t-_q*_b
        _q = int(_c//_d)
        _r = _c%_d
    _x = _a
    _y = _b
    return _d,_x
    
def excrt():
    x=0
    y=0
    k=0
    gcd=0
    M=bi[1]
    ans=ai[1]
    #print(ai[1],bi[1])
    i=2
    while(i<=n):
        
        a=M
        b=bi[i]
        c=(ai[i]-ans%b+b)%b
        
        gcd,x=ggcd(a,b)
        bg=b//gcd
        
        if(c%gcd!=0):
            return -1
        x=(x*c//gcd)%bg
        ans=ans+(x*M)
        M=M*bg
        ans=(ans+M)%M
        #print(M,ans,a,b,c,gcd,bg,x)
        i=i+1
    return (ans%M+M)%M
#xx=0
#yy=0
#print(exgcd(3,6,xx,yy))
n,m = map(int,input().split())
i=1
ai.append(0)
bi.append(0)
while(i<=n):
    u,v=map(int,input().split())
    bi.append(u)
    ai.append(v)
    i=i+1
anss=excrt()
if(anss<0):
    print("he was definitely lying")
elif (ANSS> m):
     Print ( " of He WAS Probably lying " )
 the else :
     Print (ANSS)
 # Do not Tucao I have mixed spaces tab

Positive Solutions: first enumeration violence, computing gcd twenty-two modulus, to determine whether congruent equation class, on condition that guarantee the solvability of the excrt the modular multiplication process into violence plus (tortoise-speed ride?) Once out of range immediately cease operations.

This method applies only to the quantity and value congruence equation are small case.

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll ans,n,a[105],p[105],base,M;

const char *definitely_lie = "he was definitely lying";
const char *probably_lie = "he was probably lying";

int main(){
    cin >> n >> M;
    for (int i=0;i<n;i++) cin >> p[i] >> a[i];
    for (int i=0;i<n;i++)
    for (int j=i+1;j<n;j++){
        ll d=__gcd(p[i],p[j]);
        if (d!=1){
            if (a[i]%d!=a[j]%d){
                puts(definitely_lie);
                return 0;
            }
        }
    }
    ans=0; base=1;
    for (int i=0;i<n;i++){
        while (ans%p[i]!=a[i]) {
            ans+=base;
            if (ans>M){
                puts(probably_lie);
                return 0;
            }
        }
        ll gg=p[i]/__gcd(base,p[i]);
        if (M/base>=gg) base*=gg;
        else {
            for (int j=i+1;j<n;j++) if (ans%p[j]!=a[j]){
                puts(probably_lie);
                return 0;
            }
            printf("%lld\n",ans);
            return 0;
        }
    }
    for (int i=0; i<n; i++) assert(ans % p[i] == a[i]);
    printf("%lld\n",ans);
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/isakovsky/p/11371739.html