一本通1657序列统计

1657:序列统计

时间限制: 1000 ms         内存限制: 524288 KB

【题目描述】

原题来自:BZOJ 4403

给定三个正整数 N,L 和 R,统计长度在 1 到 N 之间,元素大小都在 L 到 R 之间的单调不降序列的数量。输出答案对 106+3 取模的结果。

【输入】

输入第一行包含一个整数 T,表示数据组数。

第二到第 T+1 行每行包含三个整数 N,L 和 RN,L 和 R 的意义如题所述。

【输出】

输出包含 T 行,每行有一个数字,表示你所求出的答案对 106+3 取模的结果。

【输入样例】

2
1 4 5
2 4 5

【输出样例】

2
5

【提示】

样例说明

对于第一组输入,满足条件的两个序列为 {4},{5}

数据范围与提示:

对于全部输入,1N,L,R109,1T100,输入数据保证 LR

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('\n')
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;
}
View Code

猜你喜欢

转载自www.cnblogs.com/gaojunonly1/p/10544288.html