You are given a function f which is defined as :
Your task is to find the value of f(N) / ( f(r)*f(N-r) )
. As it will be a large number output it modulo M.
Input
First line contains T , number of test cases to follow.
Next follows T test case.
First line of ever test case contain 3 space separated integers N , M and Q.
Next Q line follows , each line contain r.
Output
For every test case , output Q lines , each line containing the answer.
Constraints
- 2 ≤ N ≤ 105
- 1 ≤ M ≤ 109
- 2 ≤ Sum of N over all test cases ≤ 5*105
- 2 ≤ Sum of Q over all test cases ≤ 105
- 1 < r < N
Subtasks
- Subtask 1: N ≤ 5 , rest of the constraints are same. Points - 9
- Subtask 2: N ≤ 500 , M is a prime number , rest of the constraints are same. Points - 31
- Subtask 3: Refer to constraints above : Points-60
Sample Input
1 5 24 2 2 3Sample Output
8 8
Explanation
f[1] = 1
f[2] = 4
f[3] = 1*22*33 = 108
f[4] =1*22*33*44 = 27648
f[5] = 1*22*33*44*55 =86400000
value of f[5] / (f[2]*f[3]) = 200000 and 200000%24 is 8
思路:假如f(x)均与m互素,那么可以预处理f(N)然后求出分子的逆元即可,由于m不一定为素数求逆元用扩展欧几里方便一点,那么目标就是将f(x)变成与m互素,即将f(1~N)分解质因子,出现f(N)的质因子均提出来另外存起来,最后分成两部分计算即可。
# include <bits/stdc++.h>
# define LL long long
# define M map<LL, LL>
# define A first
# define B second
using namespace std;
const int maxn = 1e5+30;
int t, n, q, cnt=2, p[maxn]={2,3};
LL gd, m, x, y, co[maxn];
M nco[maxn];
void init()
{
for(int i=5, j=0; i<maxn-1; ++i,j=0)
{
for(;p[j]<=sqrt(i); ++j)
if(i%p[j] == 0)
break;
if(i%p[j] !=0 ) p[cnt++] = i;
}
}
LL qmod(LL a, LL b)
{
LL ans = 1;
for(;b;b>>=1)
{
if(b&1) ans = ans*a%m;
a =a*a%m;
}
return ans;
}
LL ex_gcd(LL a, LL b)
{
if(b == 0)
{
x = 1;
y = 0;
return a;
}
gd = ex_gcd(b, a%b);
LL t = x;
x = y;
y = t-(a/b)*y;
return gd;
}
int main()
{
init();
scanf("%d",&t);
while(t--)
{
scanf("%d%lld%d",&n,&m,&q);
for(int i=1; i<=n; ++i) co[i] = 1LL, nco[i].clear();
for(int i=0; p[i]<=n; ++i)
{
for(int j=1; j*p[i]<=n; ++j)
{
LL tmp = j*p[i], tot=0, num = tmp;
while(tmp%p[i] == 0)
++tot, tmp /= p[i];
tot = num*tot;
if(__gcd(m, (LL)p[i]) != 1)
nco[num][p[i]] += tot;
else
co[num] = co[num]*qmod(p[i], tot)%m;
}
}
for(int i=2; i<=n; ++i)
{
co[i] = co[i] * co[i-1]%m;
for(auto it = nco[i-1].begin(); it != nco[i-1].end(); ++it)
nco[i][it->A] += it->B;
}
while(q--)
{
LL r;
scanf("%lld",&r);
LL ans = co[r]*co[n-r]%m;
ex_gcd(ans, m);
ans = (x%m+m)%m;
for(auto it = nco[n].begin(); it != nco[n].end(); ++it)
{
LL tmp = qmod(it->A, it->B - nco[r][it->A] - nco[n-r][it->A]);
ans = ans*tmp%m;
}
ans = ans*co[n]%m;
printf("%lld\n",ans);
}
}
return 0;
}