扩展欧几里德解的数量(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;
}
时间: 2024-10-13 10:41:26

扩展欧几里德解的数量(51nod 1352)的相关文章

扩展欧几里德--解的个数

解的个数 已知整数x,y满足如下面的条件: ax+by+c = 0 p<=x<=q r<=y<=s 求满足这些条件的x,y的个数. 输入描述 Input Description 第一行有一个整数n(n<=10),表示有n个任务.n<=10 以下有n行,每行有7个整数,分别为:a,b,c,p,q,r,s.均不超过108. 输出描述 共n行,第i行是第i个任务的解的个数. 样例输入 2 2 3 -7 0 10 0 10 1 1 1 -10 10 -9 9 样例输出 1 19

URAL 1204. Idempotents 扩展欧几里德

题目来源:URAL 1204. Idempotents 题意:输入n(n = p*q p,q是质数) 并且x*x=x(mod n) 求x 思路: x*x=x(mod n)  -> x*x+k*n=x -> x*(x-1)/n = k 所以 0 和 1 是一组解 因为n = p*q 且x*(x-1)%(p*q)== 0 x < n 因为x*x%n == x 模n之后才是x 1.x有p因子x-1有q因子 x%p == 0且(x-1)%q == 0 a*p == x且b*q == x-1 得到

扩展欧几里德算法详解

扩展欧几里德算法 谁是欧几里德?自己百度去 先介绍什么叫做欧几里德算法 有两个数 a b,现在,我们要求 a b 的最大公约数,怎么求?枚举他们的因子?不现实,当 a b 很大的时候,枚举显得那么的na?ve ,那怎么做? 欧几里德有个十分又用的定理: gcd(a, b) = gcd(b , a%b) ,这样,我们就可以在几乎是 log 的时间复杂度里求解出来 a 和 b 的最大公约数了,这就是欧几里德算法,用 C++ 语言描述如下: 由于是用递归写的,所以看起来很简洁,也很好记忆.那么什么是扩

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

题目地址:51Nod 1256 题意:给出2个数M和N(M < N),且M与N互质,找出一个数K满足0 < K < N且K * M % N = 1,如果有多个满足条件的,输出最小的. 思路:K*M%N=1可以写成K*M-Y*N=1,这样公式就变成了扩展欧几里德求K值.因为是要求最小的,所以求出特解K以后,要变成(K%N+N)%N. #include <stdio.h> #include <math.h> #include <string.h> #inc

欧几里德和扩展欧几里德详解 以及例题CodeForces 7C

欧几里德定理: 对于整数a,b来说,gcd(a, b)==gcd(b, a%b)==d(a与b的最大公约数),又称为辗转相除法 证明: 因为a是d的倍数,b是d的倍数:所以a%d==0:b%d==0: 设k=a/b:r=a%b:则 a=k*b+r: 由上得出:r=a-k*b: 因为a和b都是d的倍数,所以(a-k*b)也是d的倍数,所以r也是d的倍数: 所以gcd(a, b)==gcd(b, a%b)==d 而为什么要证明gcd(a, b)==gcd(b, a%b)==d这个式子成立呢? 其实证

欧几里德及扩展欧几里德——详解

欧几里德定理: 对于整数a, b来说有,gcd (a, b) == gcd (b, a%b) == d,又称为辗转相除法. 欧几里德证明: 先进行设定:x, y, t, k 为整数,并且有d*x == a, d*y == b. t = a - b. k = a / b. 那么t = d*x - d*k*y; t = d * (x - k * y); 故 t % d == 0; 所以gcd (b, t) == d == gcd (b, a%b) == gcd (a, b); 证毕. 欧几里德应用:

51nod 1352:集合计数

1352 集合计数 基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题  收藏  关注 给出N个固定集合{1,N},{2,N-1},{3,N-2},...,{N-1,2},{N,1}.求出有多少个集合满足:第一个元素是A的倍数且第二个元素是B的倍数. 提示: 对于第二组测试数据,集合分别是:{1,10},{2,9},{3,8},{4,7},{5,6},{6,5},{7,4},{8,3},{9,2},{10,1}.满足条件的是第2个和第8个. Input 第1行:1

POJ2142 The Balance (扩展欧几里德)

本文为博主原创文章,欢迎转载,请注明出处 www.cnblogs.com/yangyaojia The Balance 题目大意  你有一个天平(天平左右两边都可以放砝码)与重量为a,b(1<=a,b<=10000)的两种砝码.让你求出一种方案称出重为c(1<=c<=50000)的物品,如有多种方案,请输出两种砝码需要数量的总和最小的方案. 输入 有若干行,每行三个数,a,b,c. 结束时用0 0 0表示. 输出 若干行,每行两个数,表示每个询问中a的数量与b的数量 如果无解输出 

POJ 2142 The Balance【扩展欧几里德】

题意:有两种类型的砝码,每种的砝码质量a和b给你,现在要求称出质量为c的物品,要求a的数量x和b的数量y最小,以及x+y的值最小. 用扩展欧几里德求ax+by=c,求出ax+by=1的一组通解,求出当x取最小合法正整数解时y的取值,当y小于0时,说明应该放在a的另一边,变为正值.同理当y取最小时,可得到另一组解,比较两组解,取最小即可. #include<stdio.h> int ex_gcd(int a,int b,int &x,int &y){ if(!b){ x=1,y=