【BZOJ 4403】 4403: 序列统计 (卢卡斯定理)

4403: 序列统计

Time Limit: 3 Sec  Memory Limit: 128 MB
Submit: 653  Solved: 320

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

 

【分析】

  跟上一题差不多。

  答案为$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 }
View Code

 

2017-04-16 14:23:06

posted @ 2017-04-16 14:22  konjak魔芋  阅读(363)  评论(0编辑  收藏  举报