1. 程式人生 > >[BZOJ 4403]序列統計

[BZOJ 4403]序列統計

一行 ont font content 復雜 bzoj names -- turn

Description

給定三個正整數N、L和R,統計長度在1到N之間,元素大小都在L到R之間的單調不降序列的數量。輸出答案對10^6+3取模的結果。

Input

輸入第一行包含一個整數T,表示數據組數。 第2到第T+1行每行包含三個整數N、L和R,N、L和R的意義如題所述。 1≤N,L,R≤10^9,1≤T≤100,輸入數據保證L≤R。

Output

輸出包含T行,每行有一個數字,表示你所求出的答案對10^6+3取模的結果。

Sample Input

2
1 4 5
2 4 5

Sample Output

2
5
//【樣例說明】滿足條件的2個序列為[4]和[5]。
因為可以相等,所以計數會不好處理
還記得上一篇的計數技巧嗎?上一篇為了方便分析答案,將所有數-i 同樣,這道題要求最長不下降,那麽+i,轉為最長上升子序列 範圍就變成[L+1,R+i],i為序列長度 顯然方案數是C(i,i+R-L)=C(R-L,i+R-L) ans=∑C(k,i+k) k=R-L 但是n很大,O(n)都不能處理 但有C(k,n)+C(k+1,n)=C(k+1,n+1) ans=C(k,1+k)+C(k,2+k).......C(k,n+k) =C(1+k,1+k)-1+C(k,1+k)+C(k,2+k)......C(k,n+k) =C(1+k,2+k)-1+C(k,2+k)......C(k,n+k)
=C(1+k,3+k)-1......... =C(1+k,n+k+1)-1 由於n,k很大,所以用Lucas定理:C(m,n)=C(m%p,n%p)*C(m/p,n/p) 為了加速lucas,所以用了階乘逆元(代碼中的A),即A[i]=1/(i!) B代表階乘
C(x,y)=B[y]*A[x]*A[y-x]%Mod 逆元用線性模逆元公式 復雜度O(Mod+logn)
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using
namespace std; 6 int Mod=1000003; 7 long long B[1000005],A[1000005]; 8 long long ans; 9 int n,l,r; 10 long long Lucas(int x,int y) 11 { 12 if (x==0) return 1; 13 int xx=x%Mod,yy=y%Mod; 14 if (xx>yy) return 0; 15 long long S=((B[yy]*A[xx])%Mod)*A[yy-xx]%Mod; 16 return (S*Lucas(x/Mod,y/Mod))%Mod; 17 } 18 int main() 19 {int T,i; 20 cin>>T; 21 A[1]=1;A[0]=1;B[0]=1; 22 for (i=2;i<=1000003;i++) 23 A[i]=((Mod-Mod/i)*A[Mod%i])%Mod; 24 for (i=1;i<=1000003;i++) 25 { 26 A[i]=(A[i]*A[i-1])%Mod; 27 B[i]=(B[i-1]*i)%Mod; 28 } 29 while (T--) 30 { 31 cin>>n>>l>>r; 32 ans=Lucas(r-l+1,r-l+n+1); 33 cout<<(ans-1+Mod)%Mod<<endl; 34 } 35 }

[BZOJ 4403]序列統計