BZOJ 4403 序列统计
4403: 序列统计
Time Limit: 3 Sec Memory Limit: 128 MBDescription
给定三个正整数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
1 4 5
2 4 5
Sample Output
2
5
//【样例说明】满足条件的2个序列为[4]和[5]。
5
//【样例说明】满足条件的2个序列为[4]和[5]。
HINT
Source
By yts1999
虽然我不会推,但是一道好的模板题。
这里有一个很好的想法对于这种单调不下降序列,就是加上它在第几位。
假设序列长度为n,区间为[l,r],首先求出这一段的答案。
对于任意一个序列,将第i个数+i,那么原来的问题就转化为了n个在[l+1,r+n]区间以内的单调递增的序列的个数。后者又相当于在[l+1...r+n]这r-l+n个数中取n个的方案数,即为C(r-l+n,n)=C(r-l+n,r-l)
公式: C(n,m)+C(n+1,m)+C(n+2,m)+...+C(n+p,m)=C(n+p+1,m+1)-C(n,m+1);
所以,答案就相当于C(r-l+1,r-l)+C(r-l+2,r-l)+...+C(r-l+n,r-l)=C(r-l+n+1,r-l+1)-C(r-l+1,r-l+1)=C(r-l+n+1,n)-1。
1 #include<iostream> 2 #include<algorithm> 3 #include<cstdio> 4 #include<cstring> 5 #include<cmath> 6 #include<cstdlib> 7 #include<vector> 8 using namespace std; 9 typedef long long ll; 10 typedef long double ld; 11 typedef pair<int,int> pr; 12 const double pi=acos(-1); 13 #define rep(i,a,n) for(int i=a;i<=n;i++) 14 #define per(i,n,a) for(int i=n;i>=a;i--) 15 #define Rep(i,u) for(int i=head[u];i;i=Next[i]) 16 #define clr(a) memset(a,0,sizeof(a)) 17 #define pb push_back 18 #define mp make_pair 19 #define fi first 20 #define sc second 21 #define pq priority_queue 22 #define pqb priority_queue <int, vector<int>, less<int> > 23 #define pqs priority_queue <int, vector<int>, greater<int> > 24 #define vec vector 25 ld eps=1e-9; 26 ll pp=1000000007; 27 ll mo(ll a,ll pp){if(a>=0 && a<pp)return a;a%=pp;if(a<0)a+=pp;return a;} 28 ll powmod(ll a,ll b,ll pp){ll ans=1;for(;b;b>>=1,a=mo(a*a,pp))if(b&1)ans=mo(ans*a,pp);return ans;} 29 void fre() { freopen("c://test//input.in", "r", stdin); freopen("c://test//output.out", "w", stdout); } 30 //void add(int x,int y,int z){ v[++e]=y; next[e]=head[x]; head[x]=e; cost[e]=z; } 31 int dx[5]={0,-1,1,0,0},dy[5]={0,0,0,-1,1}; 32 ll read(){ ll ans=0; char last=' ',ch=getchar(); 33 while(ch<'0' || ch>'9')last=ch,ch=getchar(); 34 while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar(); 35 if(last=='-')ans=-ans; return ans; 36 } 37 const int N=1000010,p=1000003; 38 ll fac[N],inv[N]; 39 ll C(ll n,ll m){ 40 if (m>n) return 0; 41 if (n<p && m<p){ 42 return (fac[n]*inv[m]*inv[n-m])%p; 43 } 44 return (C(n/p,m/p)*C(n%p,m%p))%p; 45 } 46 void Init(){ 47 fac[0]=1; 48 for (int i=1;i<N;i++) fac[i]=(fac[i-1]*i)%p; 49 inv[1]=1; 50 for (int i=2;i<N;i++) inv[i]=((p-p/i)*inv[p%i])%p; 51 inv[0]=1; 52 for (int i=1;i<N;i++) inv[i]=(inv[i-1]*inv[i])%p; 53 } 54 int main(){ 55 Init(); 56 int T=read(); 57 while (T--){ 58 int n=read(),L=read(),R=read(); 59 printf("%lld\n",C(R-L+n+1,n)-1); 60 } 61 return 0; 62 }