【BZOJ 4403】 4403: 序列统计 (卢卡斯定理)
4403: 序列统计
Time Limit: 3 Sec Memory Limit: 128 MB
Submit: 653 Solved: 320Description
给定三个正整数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 5Sample Output
25
HINT
提示
【样例说明】满足条件的2个序列为[4]和[5]。
【数据规模和约定】对于100%的数据,1≤N,L,R≤10^9,1≤T≤100,输入数据保证L≤R。Source
【分析】
跟上一题差不多。
答案为$C_{n+r-l+1}{r-l+1}-1$
用卢卡斯定理即可。
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm> 6 using namespace std; 7 #define Mod 1000003 8 #define Maxn 1000010 9 #define LL long long 10 11 int pw[Maxn],inv[Maxn]; 12 13 void init() 14 { 15 pw[0]=1;for(int i=1;i<=Mod;i++) pw[i]=1LL*pw[i-1]*i%Mod; 16 inv[1]=1;for(int i=2;i<=Mod;i++) inv[i]=1LL*(Mod-Mod/i)*inv[Mod%i]%Mod; 17 inv[0]=1;for(int i=1;i<=Mod;i++) inv[i]=1LL*inv[i]*inv[i-1]%Mod; 18 } 19 20 int get_c(int n,int m) 21 { 22 if(n<m) return 0; 23 return 1LL*pw[n]*inv[m]%Mod*inv[n-m]%Mod; 24 } 25 26 int lucas(int n,int m) 27 { 28 if(n<m) return 0; 29 int ans=1; 30 while(n&&m) 31 { 32 ans=1LL*ans*get_c(n%Mod,m%Mod)%Mod; 33 n/=Mod;m/=Mod; 34 } 35 return ans; 36 } 37 38 int main() 39 { 40 int T; 41 scanf("%d",&T); 42 init(); 43 while(T--) 44 { 45 int n,l,r; 46 scanf("%d%d%d",&n,&l,&r); 47 int m=r-l+1; 48 int ans=lucas(n+m,m)-1; 49 ans=(ans%Mod+Mod)%Mod; 50 printf("%d\n",ans); 51 // printf("%d\n",lucas(n+m,m)-1); 52 } 53 return 0; 54 }
2017-04-16 14:23:06