模數大於n時直接用階乘逆元求就行,否則可以用Lucas求。
模數較小時預處理階乘優化。
#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define ll long long
ll qpow(ll a,ll b,ll mod)
{
ll ans=1;
while(b)
{
if(b&1)
ans=(ans*a)%mod;
a=(a*a)%mod;
b/=2;
}
return ans;
}
ll C(ll n,ll m,ll mod)
{
if(m>n)
return 0;
ll up=1,down=1;
for(ll i=n-m+1; i<=n; i++)
up=(up*i)%mod;
for(ll i=1; i<=m; i++)
down=(down*i)%mod;
return (up*qpow(down,mod-2,mod))%mod;
}
ll lucas(ll n,ll m,ll mod)
{
if(m==0)
return 1;
return (C(n%mod,m%mod,mod)*lucas(n/mod,m/mod,mod))%mod;
}
ll n,mod,t,ans,dp[1000006][2];
int main()
{
cin>>t;
while(t--)
{
ans=0;
cin>>n>>mod;
dp[0][1]=1;
dp[0][0]=0;
for(int i=1;i<=n;i++)
{
dp[i][1]=(dp[i-1][1]+dp[i-1][0])%mod;
dp[i][0]=dp[i-1][1]%mod;
}
ans=(dp[n][0]+dp[n][1])%mod;
if(n%2==0)
{
ans=(ans+lucas(n,n/2,mod))%mod;
ans=(ans-lucas(n/2+1,n/2,mod))%mod;
}
while(ans<0)
ans+=mod;
cout<<ans<<endl;
}
return 0;
}