Bzoj 4403: 序列统计 Lucas定理,组合数学,数论

4403: 序列统计

Time Limit: 3 Sec  Memory Limit: 128 MB
Submit: 328  Solved: 162
[Submit][Status][Discuss]

Description

给定三个正整数N、L和R,统计长度在1到N之间,元素大小都在L到R之间的单调不降序列的数量。输出答案对10^6+3取模的结果。

Input

输入第一行包含一个整数T,表示数据组数。第2到第T+1行每行包含三个整数N、L和R,N、L和R的意义如题所述。

Output

输出包含T行,每行有一个数字,表示你所求出的答案对106+3取模的结果。

Sample Input

21 4 52 4 5

Sample Output

25

HINT

提示

【样例说明】满足条件的2个序列为[4]和[5]。

【数据规模和约定】对于100%的数据,1≤N,L,R≤10^9,1≤T≤100,输入数据保证L≤R。

Source

By yts1999

题解:

Lucas定理+组合数学

公式推导见:http://blog.csdn.net/lych_cys/article/details/50616439

公式化简见:http://blog.csdn.net/popoqqq/article/details/50636866

化简:

设k=r-l;

ans=∑(i=1……n)C(i+k,k)

可以利用杨辉三角,C(n,m)=C(n-1,m)+C(n-1,m-1);

ans=C(1+k,k)+C(2+k,k)+C(3+k,k)+……+C(n+k,k)

     =C(1+k,1+k)-1+C(1+k,k)+C(2+k,k)+C(3+k,k)+……+C(n+k,k)

     =(C(1+k,1+k)+C(1+k,k))+C(2+k,k)+C(3+k,k)+……+C(n+k,k)-1

     =(C(2+k,1+k)+C(2+k,k))+C(3+k,k)+……+C(n+k,k)-1

     =(C(3+k,1+k)+C(3+k,k))+……+C(n+k,k)-1

     ……

     =C(n+k+1,k+1)-1

直接Lucas定理搞就可以了

注意输出要写 ((ans-1LL)%MOD+MOD)%MOD ,要不会WA(输出-1了)

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define MOD 1000003
 4 #define LL long long
 5 LL jc[MOD+10];
 6 int read()
 7 {
 8     int s=0,fh=1;char ch=getchar();
 9     while(ch<'0'||ch>'9'){if(ch=='-')fh=-1;ch=getchar();}
10     while(ch>='0'&&ch<='9'){s=s*10+(ch-'0');ch=getchar();}
11     return s*fh;
12 }
13 LL ksm(LL bb,LL pp,LL kk)
14 {
15     LL s=1LL;
16     while(pp>0LL)
17     {
18         if(pp%2LL!=0LL)s=(s*bb)%kk;
19         pp/=2LL;
20         bb=(bb*bb)%kk;
21     }
22     return s;
23 }
24 LL C(int n,int m,int P)
25 {
26     if(m>n)return 0LL;
27     if(n-m<m)m=n-m;
28     return (jc[n]*ksm((jc[m]*jc[n-m])%P,P-2,P))%P;
29 }
30 LL Lucas(int n,int m,int P)
31 {
32     if(m==0)return 1LL;
33     return (C(n%P,m%P,P)*Lucas(n/P,m/P,P))%P;
34 }
35 void cljc()
36 {
37     jc[0]=1LL;
38     for(int i=1;i<=MOD;i++)jc[i]=(jc[i-1]*i)%MOD;
39 }
40 int main()
41 {
42     int k,l,r,n,T;
43     LL ans;
44     cljc();
45     T=read();
46     while(T--)
47     {
48         n=read();l=read();r=read();
49         k=r-l;
50         ans=Lucas(k+n+1,k+1,MOD);
51         printf("%lld
",((ans-1LL)%MOD+MOD)%MOD);
52     }
53     fclose(stdin);
54     fclose(stdout);
55     return 0;
56 }
原文地址:https://www.cnblogs.com/Var123/p/5546290.html