4403: 序列统计
Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 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
Sample Output
HINT
提示
【样例说明】满足条件的2个序列为[4]和[5]。
【数据规模和约定】对于100%的数据,1≤N,L,R≤10^9,1≤T≤100,输入数据保证L≤R。
Source
题解:
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 }