1657:序列统计
时间限制: 1000 ms 内存限制: 524288 KB
提交数: 178 通过数: 92
【题目描述】
原题来自:BZOJ 4403
给定三个正整数 N,L 和 R,统计长度在 1 到 N 之间,元素大小都在 L 到 R 之间的单调不降序列的数量。输出答案对 106+3 取模的结果。
【输入】
输入第一行包含一个整数 T,表示数据组数。
第二到第 T+1 行每行包含三个整数 N,L 和 R,N,L 和 R 的意义如题所述。
【输出】
输出包含 T 行,每行有一个数字,表示你所求出的答案对 106+3 取模的结果。
【输入样例】
2
1 4 5
2 4 5
【输出样例】
2
5
【提示】
样例说明
对于第一组输入,满足条件的两个序列为 {4},{5}。
数据范围与提示:
对于全部输入,1≤N,L,R≤109,1≤T≤100,输入数据保证 L≤R。
#include <iostream>
using namespace std;
#define ll long long
const ll mod=1e6+3;
const ll maxn=mod+2;
ll list[maxn];
ll revs[maxn];
inline ll ext_gcd(ll a,ll b,ll &x,ll &y)
{
if(b==0)
{
x=1;y=0;
return a;
}
ll r=ext_gcd(b,a%b,y,x);//x=y' y=x'-(a/b)*y' -> y=x' x=y'
y-=(a/b)*x;
return r;
}
ll res(ll a)
{
ll x,y;
ext_gcd(a,mod,x,y);
return x>0?x%mod:(x%mod+mod)%mod;
}
ll pows(ll x,ll b)
{
ll ans=1;
while(b)
{
if(b&1)
ans=ans*x%mod;
x=x*x%mod;
b>>=1;
}
return ans;
}
void init()
{
list[0]=1;
revs[0]=res(list[0]);
for(int i=1;i<maxn;i++)
{
list[i]=list[i-1]*i%mod;
revs[i]=res(list[i]);
}
}
ll getC_(ll m,ll n)
{
ll ansm=1,ansn=1;
for(int i=1;i<=n;i++)
{
ansm=ansm*(m-i+1);
ansn=ansn*i;
}
return ansm/ansn;
}
ll getA(ll m,ll n)
{
if(m<n)return 0;
return list[m]*revs[m-n]%mod;
}
ll getC(ll m,ll n)
{
if(m<n)return 0;
return getA(m,n)*revs[n]%mod;
}
ll lucas(ll m,ll n)
{
if(n==0)return 1;
else return getC(m%mod,n%mod)*lucas(m/mod,n/mod)%mod;
}
int main(int argc, char** argv) {
init();
int t;
cin>>t;
while(t--)
{
ll x,l,r;
cin>>x>>l>>r;
ll len=(r-l+1);
cout<<(lucas(len+x,x)-1+mod)%mod<<endl;
}
return 0;
}