A/B
要求(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
思路1:
- 因为A能B整除,所以可以设A=k*B
- 根据题意n=A%9973,那么n = (k*B)%9973 ==> k*B = t*9973+n ==> B*k+9973*t = n
- 变成了解二元一次方程,使用扩展欧几里得可以解得k,但是单单解得k还不够,因为k是大于0的,所以要将小于0的k转化为第一个大于0的数,k = (k%9973+9973)%9973,之后使用k%9973既是答案
思路2:
- (A/B)%9973可以转化为B的乘法逆元
- x为B的乘法逆元,原式可以转化为x*A%9973
- A%9973就是题目是给的n,算出结果n*x即可,但是n*x可能会大于9973,所以最后结果还要%9973
AcCode1:
import java.util.Scanner; public class Main{ public static void main(String[] args) { Scanner in = new Scanner(System.in); int T = in.nextInt(); while(T!=0) { long n = in.nextLong(); long B = in.nextLong(); try { Ext_gcd.lineSovle(B, 9973,n); long res = Ext_gcd.x; res = (res%9973+9973)%9973; System.out.println(res%9973); } catch (Exception e) { // TODO Auto-generated catch block System.out.println("无解"); } T--; } } private static class Ext_gcd{ public static long x; public static long y; public static long ext_gcd(long a,long b) { if(b==0) { x = 1; y = 0; return a; } long d = ext_gcd(b, a%b); long x1 = x; x = y; y = x1-(a/b)*y; return d; } public static void lineSovle(long a,long b,long m) throws Exception { long d = ext_gcd(a, b); if(m%d!=0) { throw new Exception("无解"); } long n = m/d; x = x*n; y = y*n; } } }
AcCode2:
import java.util.Scanner; public class Main { //HDU-1576 public static void main(String[] args) { Scanner in = new Scanner(System.in); int T = in.nextInt(); while(T!=0) { long n = in.nextLong(); long B = in.nextLong(); Exd_gcd.reserveSolve(B, 9973); long x = Exd_gcd.x; System.out.println((x*n)%9973); T--; } } private static class Exd_gcd{ public static long x; public static long y; public static long exd_gcd(long a,long b) { if(b==0) { x = 1; y = 0; return a; } long d = exd_gcd(b, a%b); long x1 = x; x = y; y = x1-(a/b)*y; return d; } public static void lineSolve(long a,long b,long m) throws Exception { long d = exd_gcd(a, b); if(m%d!=0) { throw new Exception("无解"); } long n = m/d; x = x*n; y = y*n; } //逆元ax≡1(mod n) public static void reserveSolve(long a,long n) { try { lineSolve(a, 9973, 1); //x一定是大于0的 x = (x%9973+9973)%9973; } catch (Exception e) { // TODO Auto-generated catch block System.out.println("无解"); } } } }