• Bzoj4403 序列统计


    Time Limit: 3 Sec  Memory Limit: 128 MB
    Submit: 566  Solved: 270

    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

    21 4 52 4 5

    Sample Output

    25

    HINT

    提示

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

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

    Source

     
     
    数学问题 组合数 lucas定理
     
    设M=R-L+1,即可用的数值的数量
    对于任意一个序列,将第i个数+i,那么原来的问题就转化为了长度为N(N=1 to n)的在[l+1,r+N]区间以内的单调递增的序列的个数。
    对于每个确定的N,答案为
    $ C_{N+M-1}^{N}  = C_{N+M-1}^{M-1} $
    所以长度为1到N之间,满足要求的序列个数为
    $sum C_{N+M-1}^{N} = sum C_{N+M-1}^{M-1}$
    尝试化简这个序列:
    根据组合数的递推性质$ C(n,m)=C(n-1,m)+C(n-1,m-1) $
    $ ans=sum_{i=1}^{N} C_{i+M-1}^{M-1} extrm +C_{M}^{M}-1 $
    $ ans=sum_{i=2}^{N} C_{i+M-1}^{M-1} extrm +C_{M+1}^{M}-1 $
    $ ans=sum_{i=3}^{N} C_{i+M-1}^{M-1} extrm +C_{M+2}^{M}-1 $
    以此类推
    $ ans=C_{M+N}^{M}-1 $
     
    得到答案就是C(n+m,m)-1,用lucas定理算出来即可
     
    蜜汁WA2次之后直接把int全开成LL,就蜜汁过了
     
     
     1 /*by SilverN*/
     2 #include<algorithm>
     3 #include<iostream>
     4 #include<cstring>
     5 #include<cstdio>
     6 #include<cmath>
     7 #include<vector>
     8 #define LL long long
     9 using namespace std;
    10 const int mod=1e6+3;
    11 const int mxn=1000010;
    12 int read(){
    13     int x=0,f=1;char ch=getchar();
    14     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    15     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
    16     return x*f;
    17 }
    18 LL pw[mxn],inv[mxn];
    19 void init(){
    20     pw[0]=1;inv[1]=1;
    21     pw[1]=1;inv[0]=1;
    22     for(int i=2;i<mxn;i++){
    23         pw[i]=(LL)pw[i-1]*i%mod;
    24         inv[i]=((-(mod/i)*(LL)inv[mod%i])%mod+mod)%mod;
    25     }
    26     return;
    27 }
    28 LL calc(int n,int m){
    29     if(n<m)return 0;
    30     int res=(LL)pw[n]*inv[pw[m]]%mod*inv[pw[n-m]]%mod;
    31     return res;
    32 }
    33 LL lucas(LL n,LL m){
    34     if(!m)return 1;
    35     return calc(n%mod,m%mod)*lucas(n/mod,m/mod)%mod;
    36 }
    37 int T,n,m,L,R;
    38 int main(){
    39     int i,j;
    40     T=read();
    41     init();
    42     while(T--){
    43         n=read();L=read();R=read();
    44         m=R-L+1;
    45         int ans=lucas((LL)n+m,m)-1;
    46         if(ans<0)ans+=mod;
    47         printf("%d
    ",ans);
    48     }
    49     return 0;
    50 }
  • 相关阅读:
    进程与线程的区别与联系
    任务、进程、线程
    类、对象、方法、实例方法、类方法
    java 泛型详解
    Java总结篇系列:Java泛型
    html+css+js 实现自动滑动轮播图
    第三篇web前端面试自我介绍(刚毕业的菜鸟)
    怎么写网站的需求文档
    在phpStudy怎么配置虚拟地址
    第二篇web前端面试自我介绍(刚毕业的菜鸟)
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/6602153.html
Copyright © 2020-2023  润新知