51nod1352(exgcd)

题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1352

题意:中文题诶~

思路:exgcd

显然题目可以描述为:求a*x+b*y=n+1中满足  1 <= x,y <=n 的解数,

可以先通过exgcd求出一组a*x+b*y=gcd(a, b)的解 x1, y1,那么对应的a*x+b*y=n+1的解就是x1*(n/gcd(a, b)), y1*(n/(gcd(a, b)),

若能求出最小的x解的话,则每隔lcm(a, b), 隔lcm(a, b)出现一组满足条件的解,所以有ans=(n-1-x*a)/lcm(a,b) + 1;

先令x=x1%b,要尽量使x小,所以将大于b的部分放到b*y中去;

令temp=x*a, cc=lcm(a, b)

则有:

  while(temp<1){
            temp+=cc;
        }
        while(temp>0){
            temp-=cc;
        }
        temp+=cc;// 第一个大于0的a*x

将其直接化为公式计算:

  if(temp<1){
            k=ceil(double(1-temp)/cc);
            temp+=cc*k;
        }else{
            k=(temp-1)/cc;
            temp-=cc*k;
        }

答案也就显而易见了,注意中间可能会爆int....

代码:

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <math.h>
 4 #define ll long long
 5 using namespace std;
 6 
 7 int exgcd(ll a, ll b, ll& d, ll& x, ll& y){
 8     if(b==0){
 9         x=1, y=0, d=a;
10     }else{
11         exgcd(b, a%b, d, y, x);
12         y-=(a/b)*x;
13     }
14 }
15 
16 int main(void){
17     int t;
18     ll n, a, b;
19     scanf("%d", &t);
20     while(t--){
21         scanf("%lld%lld%lld", &n, &a, &b);
22         ll x, y, d;
23         exgcd(a, b, d, x, y);
24         if((++n)%d){ //a*x+b*y=c 当且仅当c=k*gcd(a,b)时有整数解
25             printf("0
");
26             continue;
27         }
28         x=x*(n/d)%b; //得到a*x+b*y=n+1的解,若x>b,将大于b的部分放到y*b中
29         ll cc=a*b/d; //lcm(a,b)
30         ll temp=x*a;
31         // while(temp<1){
32         //     temp+=cc;
33         // }
34         // while(temp>0){
35         //     temp-=cc;
36         // }
37         // temp+=cc;// 第一个大于0的a*x
38         ll k;
39         if(temp<1){
40             k=ceil(double(1-temp)/cc);
41             temp+=cc*k;
42         }else{
43             k=(temp-1)/cc;
44             temp-=cc*k;
45         }
46         if(temp>=n){
47             printf("0
");
48         }else{
49             printf("%lld
", (n-temp-1)/cc+1);//前面给n加了1,但求出的b*y要<=n
50         }
51     }
52     return 0;
53 }
View Code
原文地址:https://www.cnblogs.com/geloutingyu/p/6700046.html