模线性方程模板

POJ2115 模线性方程

View Code
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

typedef __int64 int64;
int64 A,B,C,K;
int64 p[35];

void get_P() {
     p[0]=1;
     for(int i=1;i<33;i++) p[i]=p[i-1]*2;
}

int64 Extend_euc(int64 a,int64 b,int64&x,int64&y) {
    if(b==0) {
        x=1, y=0;
        return a;
    }
    int64 d,tmp;
    d=Extend_euc(b,a%b,x,y);
    tmp=x;
    x=y;
    y=tmp-(a/b)*y;
    return d;
}

void solve() {
     int64 i,j,k,d,x,y,ans;
     int64 tmp=B-A;
     d=Extend_euc(C,p[K],x,y);
     if(tmp%d) puts("FOREVER");
     else {
         ans=(tmp/d*x)%p[K]+p[K];
         printf("%I64d\n",ans%(p[K]/d));
     }
}
int main() {
    get_P();
    while(scanf("%I64d%I64d%I64d%I64d",&A,&B,&C,&K),A+B+C+K) solve();
    return 0;
}

 扩展 GCD: 求x, y使得gcd(a, b) = a * x + b * y;

View Code
/*=======================================*\
扩展GCD:求x, y使得gcd(a, b) = a * x + b * y;
\*=======================================*/
int Extend_euc(int a,int b,int&x,int&y) {
    if(b==0) { x=1, y=0; return a;}
    int d=Extend_euc(b,a%b,x,y);
    int tmp=x; x=y; y=tmp-(a/b)*y;
    return d;
}

模线性方程 a * x = b (% n)

View Code
/*=====================================*\
| 模线性方程 a * x = b (% n)
\*=====================================*/
void modeq(int a, int b, int n) {// !n>0
    int e,i,d,x,y;
    d=extgcd(a,n,x,y);
    if(b%d > 0) puts("No answer!");
    else {
        e = (x*(b/d))%n;
        for(i=0; i<d; i++) // !!! here x maybe < 0
            printf("%d-th ans: %d\n",i+1,(e+i*(n/d))%n);
    }
}

中国余数定理 其中r, a已知,a[i]>0且a[i]与a[j]互质, 求ans;

View Code
/*==================================================*\
| 模线性方程组
| ans=r[1](% a[1]); ans=r[2](% a[2]); ... ans=r[N](% a[N]);
| 其中r, a已知,a[i]>0且a[i]与a[j]互质, 求ans; (中国余数定理)
\*==================================================*/
void china() {
    int64 i,j,k;
    int64 a1,r1,a2,r2,d,x,y,tmp;
    bool flag=true;
    scanf("%I64d%I64d",&a1,&r1);
    for(i=1;i<N;i++) {
        scanf("%I64d%I64d",&a2,&r2);
        if(!flag) continue;
        tmp=r2-r1;
        d=Extend_euc(a1,a2,x,y);
        if(tmp%d) {flag=false;r1=-1;continue;} //无解
        r1=((tmp/d*x)%a2+a2)%(a2/d)*a1+r1;
        a1=a1/d*a2;
    }
    printf("%I64d\n",r1);
}

int main() {
    while(scanf("%I64d",&N)!=EOF) china();
    return 0;
}

 

posted @ 2012-12-28 19:55  zhang1107  阅读(180)  评论(0编辑  收藏  举报