887. 求组合数 III
给定 n 组询问,每组询问给定三个整数 a,b,p,其中 p 是质数,请你输出3. 卢卡斯定理 - 图1的值。
输入格式
第一行包含整数 n。
接下来 n 行,每行包含一组 a,b,p。
输出格式
共 n 行,每行输出一个询问的解。
数据范围
1≤n≤20
1≤b≤a≤1018,
1≤p≤105,
输入样例:

  1. 3
  2. 5 3 7
  3. 3 1 5
  4. 6 4 13

输出样例:

  1. 3
  2. 3
  3. 2

要素

  • 1≤n≤20
  • 1≤b≤a≤1018,
  • 1≤p≤105,

卢卡斯定理

卢卡斯定理.pdf

  1. import java.util.*;
  2. public class Main {
  3. public static void main(String[] args) {
  4. Scanner sc = new Scanner(System.in);
  5. int m = sc.nextInt();
  6. while (m-- > 0) {
  7. long a = sc.nextLong(), b = sc.nextLong();
  8. int p = sc.nextInt();
  9. int res = lucas(a, b, p);
  10. System.out.println(res);
  11. }
  12. }
  13. static int lucas(long a, long b, int p) {
  14. if (a < p) return C((int)a, (int)b, p);
  15. else return (int)(1L * C((int)(a % p), (int)(b % p), p) * lucas(a / p, b / p, p) % p);
  16. }
  17. static int C(int a, int b, int p) {
  18. int res = 1;
  19. for (int i = 1, j = a; i <= b; i++, j--) {
  20. res = (int)(1L * res * j % p);
  21. res = (int)(1L * res * qmi(i, p-2, p) % p);
  22. }
  23. return res;
  24. }
  25. static int qmi(long a, long b, long p) {
  26. int res = 1;
  27. while (b > 0) {
  28. if ((b & 1) == 1) {
  29. res = (int)(res * a % p);
  30. }
  31. a = a * a % p;
  32. b >>= 1;
  33. }
  34. return res;
  35. }
  36. }