【BZOJ】【lucas定理】4403: 序列统计

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/FYOIER/article/details/82191841

m=RL+1如果长度确定为n,相当于求i=1mxi=n,用插板法得答案为(n+m1m1),然后就是一波骚操作:

(xy)=(x1y)+(x1y1)

i=1n(i+m1m1)=(n+m1n)+(n1+m1n1)+...+(m+12)+(m1)+(m0)1=i=1n(i+m1m1)=(n+m1n)+(n1+m1n1)+...+(m+12)+(m+11)1=(n+mn)1

由于范围较大,但是注意到模数是质数,直接用lucas定理就可以了。

代码

#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;
}
展开阅读全文

没有更多推荐了,返回首页