题目链接:https://www.acwing.com/problem/content/description/889/
 时/空限制:1s / 64MB
题目描述
给定n组询问,每组询问给定三个整数a,b,p,其中p是质数,请你输出的值。
输入格式
第一行包含整数n。
接下来n行,每行包含一组a,b,p。
输出格式
共n行,每行输出一个询问的解。
数据范围
1≤n≤20,
1≤b≤a≤10^18,
1≤p≤10^5,
输入样例
3
5 3 7
3 1 5
6 4 13
输出样例
3
3
2
解题思路
题意:求的值。
思路:
- 100000组, 1 <= b <= a <= 2000, 递推 -> O(N^2).
 - 10000组, 1 <= b <= a <= 10^5, 预处理 -> O(NlogN).
 - 20组, 1 <= b <= a <= 10^18, p <= 10^5, 卢卡斯定理(lucas)
 
Accepted Code:
/* 
 * @Author: lzyws739307453 
 * @Language: C++ 
 */
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int Fast_Power(int a, int b, int p) {
    int res = 1;
    while (b) {
        if (b & 1)
            res = 1ll * res * a % p;
        a = 1ll * a * a % p;
        b >>= 1;
    }
    return res;
}
int Com_Num(int a, int b, int p) {
    int res = 1;
    for (int i = 1, j = a; i <= b; i++, j--)
        res = 1ll * res * j % p * Fast_Power(i, p - 2, p) % p;
    return res;
}
int lucas(ll a, ll b, int p) {
    if (a < p && b < p)
        return Com_Num(a, b, p);
    return 1ll * Com_Num(a % p, b % p, p) * lucas(a / p, b / p, p) % p;
}
int main() {
    int t;
    scanf("%d", &t);
    while (t--) {
        int p;
        ll a, b;
        scanf("%lld%lld%d", &a, &b, &p);
        printf("%d\n", lucas(a, b, p));
    }
    return 0;
}
京公网安备 11010502036488号