zoukankan      html  css  js  c++  java
  • hdu1576 扩展欧几里德 A/B

    A/B

    Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 6784    Accepted Submission(s): 5389


    Problem Description
    要求(A/B)%9973,但由于A很大,我们只给出n(n=A%9973)(我们给定的A必能被B整除,且gcd(B,9973) = 1)。
     
    Input
    数据的第一行是一个T,表示有T组数据。
    每组数据有两个数n(0 <= n < 9973)和B(1 <= B <= 10^9)。
     
    Output
    对应每组数据输出(A/B)%9973。
     
    Sample Input
    2
    1000 53
    87 123456789
     
    Sample Output
    7922
    6060
     
    Author
    xhd

    扩展欧几里得的模板题,要记住:

    x=y1;

    y=x1-a/b*y1。

    这道题的推导过程如下:

    1.因为A%B==0,所以令A/B=x,即A=Bx。又因为n=A%m,所以m*y+n=A。

    由上面可推导出Bx-my=n。

    2.由扩展欧几里得算法可以算出B*x1+m*y1=1的根,等式两边同时乘上n可以变形为B*(x1*n)-m*(-n*y1)=n。

    所以x=n*x1。到这里我们只需要通过扩欧算出x1,答案即为(x1*n)%m。

    3.最后要注意的一点,扩展欧几里得算法算出的x1可能为负数,这显然是不成立的。又因为

    x=x1+b*t;

    y=y1-a*t;

    所以x1的值可以写成(x%m+m)%m。这样的话负数也转成了正数,就可以输出答案啦!

     
    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    const int m = 9973;
    void exgcd(int a,int b,int &x,int &y){
        if(b == 0){
            x = 1;
            y = 0;
            return;
        }
        exgcd(b,a%b,x,y);
        int t = y;
        y = x - a/b*y;
        x = t;
    }
    int main(){
        int T;
        cin >> T;
        while(T--){
            int n,b,x,y;
            cin >> n >> b;
            exgcd(b,m,x,y);
            x = (x%m+m)%m;//防止x为负数
            cout << x*n%m << endl;
        } 
        return 0; 
    }
    彼时当年少,莫负好时光。
  • 相关阅读:
    C# 高效字符串连接 StringBuilder介绍
    C#图解教程
    C#中string类型是值类型还是引用类型?
    UML类图10分钟快速入门
    C#设计模式--单例模式
    计算机是如何启动的?
    2018年计划
    转:SQL进阶之变量、事务、存储过程与触发器
    2020/02/06,武汉
    2020/02/06,渐渐,from eason for you for her
  • 原文地址:https://www.cnblogs.com/l609929321/p/7778060.html
Copyright © 2011-2022 走看看