求非降序列可以考虑将每一个位置加上i,变成求严格上升序列。
那么长度为
i
,范围在
令
M=r−l+1
ans=∑i=1nCiM+i−1
=C1M+C2M+1+C3M+2+…+CNM+N−1
=−1+C0M+C1M+C2M+1+C3M+2+…+CNM+N−1
=CNM+N−1
因为 n,m 较大,用 Lucas 定理解决。
如果要预处理逆元,要用线性方法。。试着用费马小定理预处理T掉了。
因为T只有100,每次计算也只有log级别,所以不预处理逆元会更快。
【代码】
不预处理。每次直接算逆元。 360ms
#include <cstdio>
#include <iostream>
#include <algorithm>
#define N 1000000
#define INF 0x7fffffff
#define mod 1000003
using namespace std;
typedef long long ll;
typedef pair<int,int> pa;
int read()
{
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return x*f;
}
int T,n,m,l,r;
int Fac[N];
int Qpow(int x,int y)
{
int rtn=1;
while(y){
if(y&1) rtn=1LL*x*rtn%mod;
x=1LL*x*x%mod;y>>=1;
}
return rtn;
}
int Lucas(int x,int y)
{
if(x<y) return 0;
if(x<mod&&y<mod) return 1LL*Fac[x]*Qpow(1LL*Fac[y]*Fac[x-y]%mod,mod-2)%mod;
return 1LL*Lucas(x/mod,y/mod)*Lucas(x%mod,y%mod)%mod;
}
int main()
{
T=read();
Fac[0]=1;
for(register int i=1;i<mod;i++) Fac[i]=(1LL*Fac[i-1]*i)%mod;
while(T--)
{
n=read(),l=read(),r=read();
m=r-l+1;
printf("%d\n",(Lucas(n+m,n)-1+mod)%mod);
}
return 0;
}
线性预处理逆元 1272ms
#include <cstdio>
#include <iostream>
#include <algorithm>
#define N 1000005
#define INF 0x7fffffff
#define mod 1000003
using namespace std;
typedef long long ll;
typedef pair<int,int> pa;
int read()
{
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return x*f;
}
int T,n,m,l,r;
ll Inv[N],Fac[N];
ll Qpow(int x,int y)
{
ll rtn=1;
while(y){
if(y&1) rtn=1LL*x*rtn%mod;
x=1LL*x*x%mod;y>>=1;
}
return rtn;
}
void Pre_Work()
{
Inv[0]=Fac[0]=Inv[1]=1;
for(int i=1;i<mod;i++) Fac[i]=(Fac[i-1]*i)%mod;
for(int i=2;i<mod;i++) Inv[i]=(mod-mod/i)*Inv[mod%i]%mod;
for(int i=1;i<mod;i++) Inv[i]=(Inv[i]*Inv[i-1])%mod;
}
ll Lucas(int x,int y)
{
if(x<y) return 0;
if(x<mod&&y<mod) return Fac[x]*Inv[y]%mod*Inv[x-y]%mod;
return Lucas(x/mod,y/mod)*Lucas(x%mod,y%mod)%mod;
}
int main()
{
T=read();
Pre_Work();
while(T--)
{
n=read(),l=read(),r=read();
m=r-l+1;
printf("%lld\n",(Lucas(n+m,n)-1+mod)%mod);
}
return 0;
}