扩展欧几里德解的数量(51nod 1352)

Posted yoyo_sincerely

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了扩展欧几里德解的数量(51nod 1352)相关的知识,希望对你有一定的参考价值。

题意;给出N,A,B;求A*x+ B*y = N+1   的大于0 的解的数量;

思路:先用exgcd求出大于0的初始解x,rest = N - x*A; sum = rest/LCM(A, B);

 

#include <iostream>
#include <algorithm>
#include <stdlib.h>
#include <time.h>
#include <cmath>
#include <cstdio>
#include <string>
#include <cstring>
#include <vector>
#include <queue>
#include <stack>
#include <set>

#define c_false ios_base::sync_with_stdio(false); cin.tie(0)
#define INF 0x3f3f3f3f
#define INFL 0x3f3f3f3f3f3f3f3f
#define zero_(x,y) memset(x , y , sizeof(x))
#define zero(x) memset(x , 0 , sizeof(x))
#define MAX(x) memset(x , 0x3f ,sizeof(x))
#define swa(x,y) {LL s;s=x;x=y;y=s;}
using namespace std ;
#define N 100005
const double PI = acos(-1.0);
typedef long long LL ;
LL x, y, A, B, n, C;
LL gcd(LL a, LL b){if(a== 0) return b;else return gcd(b%a,a);}

LL exgcd(LL a, LL b, LL &x, LL &y){
    if(b == 0){
        x = 1; y = 0;return a;
    }else{
    LL t = exgcd(b, a%b, y, x);
    y -= (a/b)*x;
    return t;
    }
}

LL cal(){
    LL sum= 0;
    LL r = exgcd(A, B, x, y);
    LL z = A*B/r;

    if((1+n)%r) return 0;
    else{
        x = x*((1+n)/r);
        LL d = B/r;
        x = (x%d + d) %d;
        if(x == 0)
            x += d;
        LL remain = n - x*A;
        if(remain < 0) return 0;
        else{
            sum++;
            sum += remain/z;
        }
    }
    return sum;
}
int main(){
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    scanf("%I64d",&C);
    for(int i = 0;i< C;i++){
        scanf("%I64d%I64d%I64d",&n, &A, &B);
        cout<<cal()<<endl;
    }
    return 0;
}

 

以上是关于扩展欧几里德解的数量(51nod 1352)的主要内容,如果未能解决你的问题,请参考以下文章

51nod 1352 集合计数 扩展欧几里得

51Nod 1352 集合计数 扩展欧几里得

51 Nod 1352 集合计数(中国剩余定理+扩展欧几里得)

51nod_1352_集合计数 (exgcd)

51nod 1256 扩展欧几里得

51Nod 1256 乘法逆元(扩展欧几里得)