• 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的意义如题所述。

    Output

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

    Sample Input

    2
    1 4 5
    2 4 5

    Sample Output

    2
    5

    HINT

    提示

    【样例说明】满足条件的2个序列为[4]和[5]。

    【数据规模和约定】对于100%的数据,1≤N,L,R≤10^9,1≤T≤100,输入数据保证L≤R。

    思路:得到一个这样的二维数组:表示第i的长度结尾为L的个数

       L     L+1      L+2    L+3    .......    R

    1      1     1          1        1        ......     1

    2      1     2          3        4        ......     R

    .....

    N     1     C(N,1)                       ......    C((R-L+1+N),N)

    答案为取一个矩阵的和,sigma;

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<string>
    #include<queue>
    #include<algorithm>
    #include<stack>
    #include<cstring>
    #include<vector>
    #include<list>
    #include<set>
    #include<map>
    using namespace std;
    #define ll long long
    #define mod 1000000007
    #define inf 999999999
    #define pi 4*atan(1)
    //#pragma comment(linker, "/STACK:102400000,102400000")
    int scan()
    {
        int res = 0 , ch ;
        while( !( ( ch = getchar() ) >= '0' && ch <= '9' ) )
        {
            if( ch == EOF ) return 1 << 30 ;
        }
        res = ch - '0' ;
        while( ( ch = getchar() ) >= '0' && ch <= '9' )
            res = res * 10 + ( ch - '0' ) ;
        return res ;
    }
    ll f[1000010];
    void init(int p) {                 //f[n] = n!
        f[0] = 1;
        for (int i=1; i<=p; ++i) f[i] = f[i-1] * i % p;
    }
    ll pow_mod(ll a, ll x, int p)   {
        ll ret = 1;
        while (x)   {
            if (x & 1)  ret = ret * a % p;
            a = a * a % p;
            x >>= 1;
        }
        return ret;
    }
    
    ll Lucas(ll n, ll k, ll p) {       //C (n, k) % p
         ll ret = 1;
         while (n && k) {
            ll nn = n % p, kk = k % p;
            if (nn < kk) return 0;                   //inv (f[kk]) = f[kk] ^ (p - 2) % p
            ret = ret * f[nn] * pow_mod (f[kk] * f[nn-kk] % p, p - 2, p) % p;
            n /= p, k /= p;
         }
         return ret;
    }
    int main()
    {
        ll x,y,z,i,t;
        init(1000003);
        int T;
        ll N,L,R;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%lld%lld%lld",&N,&L,&R);
            ll n,k;
            ll ans=0;
            k=N;
            n=(R-L+1+N);
            ans+=Lucas(n,k,1000003);
            printf("%lld
    ",(ans+1000002)%1000003);
        }
        return 0;
    }
  • 相关阅读:
    直接插入排序
    安卓突击:隐式、显式Intent
    安卓突击:Android 动画有哪几种?
    安卓突击:ANR
    安卓突击:系统上安装了多种浏览器,能否指定某浏览器访问指定页面
    安卓突击:系统上安装了多种浏览器,能否指定某浏览器访问指定页面
    Android:BroadcastReceiver的基础知识
    安卓突击:service的基础知识
    安卓突击:数据存储方式
    Android突击:常用的五种布局
  • 原文地址:https://www.cnblogs.com/jhz033/p/5484058.html
Copyright © 2020-2023  润新知