令m=R−L+1m=R−L+1如果长度确定为nn,相当于求,用插板法得答案为(n+m−1m−1)(n+m−1m−1),然后就是一波骚操作:
由(xy)=(x−1y)+(x−1y−1)(xy)=(x−1y)+(x−1y−1)
∑i=1n(i+m−1m−1)=(n+m−1n)+(n−1+m−1n−1)+...+(m+12)+(m1)+(m0)−1=∑i=1n(i+m−1m−1)=(n+m−1n)+(n−1+m−1n−1)+...+(m+12)+(m+11)−1=(n+mn)−1∑i=1n(i+m−1m−1)=(n+m−1n)+(n−1+m−1n−1)+...+(m+12)+(m1)+(m0)−1=∑i=1n(i+m−1m−1)=(n+m−1n)+(n−1+m−1n−1)+...+(m+12)+(m+11)−1=(n+mn)−1
由于范围较大,但是注意到模数是质数,直接用lucaslucas定理就可以了。
代码
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
const int tt=1000003;
int T,f[tt+6],inv[tt+6];
int C(int x,int y){if(x<y)return 0;return (LL)f[x]*inv[y]%tt*inv[x-y]%tt;}
int lucas(int x,int y){if(!y)return 1;return (LL)C(x%tt,y%tt)*lucas(x/tt,y/tt)%tt;}
int main(){
freopen("sequence.in","r",stdin);freopen("sequence.out","w",stdout);
f[0]=inv[0]=inv[1]=1;
for(int i=1;i<=tt;i++)f[i]=(LL)f[i-1]*i%tt;
for(int i=2;i<=tt;i++)inv[i]=(tt-(LL)tt/i*inv[tt%i]%tt)%tt;
for(int i=2;i<=tt;i++)inv[i]=(LL)inv[i-1]*inv[i]%tt;
scanf("%d",&T);
for(int n,l,r;T;T--)scanf("%d%d%d",&n,&l,&r),printf("%d\n",(lucas(r-l+1+n,n)-1+tt)%tt);
return 0;
}

博客围绕代码中的数学计算展开,当长度确定为n时,通过插板法求∑mi=1xi=n的答案为(n+m−1m−1),还提及由(xy)=(x−1y)+(x−1y−1)进行后续操作。

468

被折叠的 条评论
为什么被折叠?



