1657:序列统计
时间限制: 1000 ms 内存限制: 524288 KB【题目描述】
原题来自: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。
sol:略有些思维难度
如果是不下降感觉非常不可做,但是严格递增就容易了
一般操作就是把第 i 个数字加上 i
这样当序列长度为n时数字个数就是R-L+n,数量就是C(R-L+n,n)
这样是O(n),所以要找规律
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
C11+C22+C33+... : 1+1+1+... (C41-1)+...
C21+C32+C43+... : 2+3+4+... (C52-1)+...
C31+C42+C53+... : 3+6+10+... (C63-1)+...
C41+C52+C63+... : 4+10+20+... (C74-1)+...
所以C(k+1,1)+C(k+2,2)+C(k+3,3)+...+C(k+n,n) = C(k+n+1,k+1)-1
套上Lucas板子就ok了
/* C(r-l+i,i) C(r-l+1,1)+C(r-l+2,2)+C(r-l+3,3) 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 1 5 10 10 5 1 1 6 15 20 15 6 1 C11+C22+C33+... : 1+1+1+... (C41-1)+... C21+C32+C43+... : 2+3+4+... (C52-1)+... C31+C42+C53+... : 3+6+10+... (C63-1)+... C41+C52+C63+... : 4+10+20+... (C74-1)+... 所以C(k+1,1)+C(k+2,2)+C(k+3,3)+...+C(k+n,n) = C(k+n+1,k+1)-1 */ #include <bits/stdc++.h> using namespace std; typedef long long ll; inline ll read() { ll s=0; bool f=0; char ch=' '; while(!isdigit(ch)) { f|=(ch=='-'); ch=getchar(); } while(isdigit(ch)) { s=(s<<3)+(s<<1)+(ch^48); ch=getchar(); } return (f)?(-s):(s); } #define R(x) x=read() inline void write(ll x) { if(x<0) { putchar('-'); x=-x; } if(x<10) { putchar(x+'0'); return; } write(x/10); putchar((x%10)+'0'); return; } #define W(x) write(x),putchar(' ') #define Wl(x) write(x),putchar(' ') const ll Mod=1000003; const int N=1000005; int T; ll Jiec[N],InvJiec[N]; inline ll Ksm(ll x,ll y) { ll ans=1; while(y) { if(y&1) ans=ans*x%Mod; x=x*x%Mod; y>>=1; } return ans; } inline ll C(ll n,ll m) { if(n<m) return 0; if(!InvJiec[m]) InvJiec[m]=Ksm(Jiec[m],Mod-2); if(!InvJiec[n-m]) InvJiec[n-m]=Ksm(Jiec[n-m],Mod-2); return Jiec[n]*InvJiec[m]%Mod*InvJiec[n-m]%Mod; } inline ll Lucas(ll n,ll m) { ll ans=1; while(n&&m) { ans=ans*C(n%Mod,m%Mod); n/=Mod; m/=Mod; } return ans; } int main() { R(T); ll i,n,l,r; Jiec[0]=1; for(i=1;i<=Mod;i++) { Jiec[i]=Jiec[i-1]*i%Mod; } while(T--) { R(n); R(l); R(r); Wl((Lucas(r-l+n+1,r-l+1)-1+Mod)%Mod); } return 0; }