题意:
给定
n
,
题解:
http://codeforces.com/blog/entry/56135
这个转化太妙了,大概是类似找代表元的思想。
之后推导后可以用扩展Lucas求组合数了,好久没有打很不熟练啊。。
#include<bits/stdc++.h>
using namespace std;
inline int rd(){
char ch=getchar();int i=0,f=1;
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch)){i=(i<<1)+(i<<3)+ch-'0';ch=getchar();}
return i*f;
}
typedef pair<int,int> pii;
const int Maxn=1e5+50;
vector<pii>fac;
int n,p,l,r,vis[Maxn][35],v[35],fac2[Maxn][35];
pii fac1[Maxn][35];
long long ans;
inline int power(int a,int b,int mod){
int rs=1;
for(;b;b>>=1,a=1ll*a*a%mod)if(b&1)rs=1ll*rs*a%mod;
return rs;
}
inline int calc_inv(int A,int id);
inline pii calc_fac(int A,int id){
if(!A)return make_pair(0,1);
if(vis[A][id])return fac1[A][id];
vis[A][id]=1;int bl=A/fac[id].first;
int t1=fac2[bl*fac[id].first][id];
int t2=1ll*fac2[A][id]*calc_inv(fac2[bl*fac[id].first][id],id)%v[id];
t1=1ll*t1*t2%v[id];
pii t3=calc_fac(bl,id);
return fac1[A][id]=make_pair(t3.first+bl,1ll*t1*t3.second%v[id]);
}
inline void exgcd(int A,int B,long long &x,long long &y){
if(!B){
x=1;y=0;return;
}
exgcd(B,A%B,x,y);
long long t=x;
x=y;
y=t-A/B*y;
}
inline int calc_inv(int A,int id){
long long x,y;
exgcd(A,v[id],x,y);
x%=v[id];x+=v[id];x%=v[id];
return x;
}
inline void merge(int &A,int &B,int C,int D){
long long k1,k2;
exgcd(A,C,k1,k2);
k1%=C;k1+=C;k1%=C;
k1=k1*(D-B);
k1%=C;k1+=C;k1%=C;
B=(k1*A+B);
A=A*C;B%=A;
}
inline int calc(int A,int B){
if(B<0)return 0;
if(!B)return 1;
int now=1,rs=0;
for(int i=0;i<fac.size();++i){
pii t1=calc_fac(A,i),t2=calc_fac(B,i),t3=calc_fac(A-B,i);
t1.first-=(t2.first+t3.first);
t1.second=1ll*t1.second*calc_inv(t2.second,i)%v[i]*calc_inv(t3.second,i)%v[i];
for(int j=1;j<=t1.first;j++)t1.second=1ll*fac[i].first*t1.second%v[i];
merge(now,rs,v[i],t1.second);
}
return rs;
}
int main(){
n=rd(),p=rd(),l=rd(),r=rd();int tt=p;
for(int i=2;i*i<=tt;++i){
if(!(tt%i)){
pii t=make_pair(i,0);v[fac.size()]=1;
while(!(tt%i))tt/=i,++t.second,v[fac.size()]*=i;
fac.push_back(t);
}
}
if(tt!=1)v[fac.size()]=tt,fac.push_back(make_pair(tt,1));
for(int i=0;i<fac.size();i++){
fac2[0][i]=1;
for(int j=1;j<=n;j++){
fac2[j][i]=1ll*fac2[j-1][i]*(j%fac[i].first?j:1)%v[i];
}
}
for(int C=0;C<=n;++C){
r=min(r,n-C);if(r<l)break;
int rs=n-C,tp=calc(n,C);
int L=l+((l&1)!=(rs&1)),R=r-((r&1)!=(rs&1));
if(L>R)continue;
ans+=calc(rs,(rs-L)/2)*1ll*tp%p;
ans-=calc(rs,(rs-R-2)/2)*1ll*tp%p;
ans%=p;ans+=p;ans%=p;
}
cout<<ans<<endl;
}