BZOJ 4403 序列统计

4403: 序列统计

Time Limit: 3 Sec  Memory Limit: 128 MB

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]。

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 } 
View Code

 

 

posted @ 2017-09-18 16:35  SXia  阅读(231)  评论(0编辑  收藏  举报