此题 上一题的升级版 。。
数据规模变大, 还要mod 一个数 。
递推公式 Cn+1 = Cn * (4n + 2) / ( n + 2)
由于 有除法 还要取模 ,那么 就要求逆元,但是给定的m 不一定和 (n+2) 互质,不能直接求 逆元,那么 就要吧 N+2 中的 和 m 相同的因子提出来 特别计算就可以。
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
int n , m;
#define LL long long
int p[25];
int num[25];
int tot;
void init_p(){
tot = 0;
int t = m;
memset(num,0,sizeof(num));
for(int i=2 ;i*i<= t;i++){
if(t%i==0){
tot ++;
p[tot] = i;
while(t%i == 0 ){
t = t/i;
}
}
}
if(t>1){
tot ++ ;
p[tot] = t;
}
}
int f(int a){
int ans = 1;
for(int i=2 ;i*i<= a;i++){
if(a%i== 0){
ans *= i -1;
a /= i;
while(a%i==0){
ans *= i;
a /= i;
}
}
}
if(a > 1){
ans *= a-1;
}
return ans;
}
LL pow(LL a,LL b){
LL ans = 1;
while(b){
if(b&1){
ans *= a;
ans %= m;
}
a = a*a ;
a%= m;
b>>=1;
}
return ans;
}
void solve(){
LL sum = 1;
LL ans = 1;
int t = f(m);
for(int i=2;i<=n;i++){
int a = 4*(i-1) +2;
int b = (i-1) + 2;
for(int j=1;j<=tot;j++){
while(a%p[j]== 0){
num[j]++;
a /= p[j];
}
}
for(int j=1;j<= tot;j++){
while(b%p[j] == 0){
num[j]--;
b/= p[j];
}
}
ans *= a;
ans %= m;
ans *= pow(b,t-1);
ans %= m;
LL tmp = ans;
for(int i=1;i<= tot;i++){
if(num[i]){
tmp *= pow(p[i],num[i]);
tmp %= m;
}
}
sum += tmp ;
sum %= m;
}
printf("%d\n",(int)sum%m);
}
int main(){
while(~scanf("%d%d",&n,&m)){
if(n == 0 && m ==0 ) break;
init_p();
solve();
}
}