码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2016-03-20 14:26:34      阅读:160      评论:0      收藏:0      [点我收藏+]

标签:

题意;给出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)

标签:

原文地址:http://www.cnblogs.com/yoyo-sincerely/p/5289677.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!