zoukankan      html  css  js  c++  java
  • bzoj4403:序列统计

    我好傻啊

    题目

    先来看看长度只能为(n)的情况

    那么答案非常显然是(inom{m+n-1}{n})

    其中(m=R-L+1)

    因为我们要构造一个非降序列,显然可能一个数会被选择多次,组合非常不好做,于是我们可以把每一个数的下标加上其对应的下标那么现在的值域范围就变成了([L+1,R+n]),从这个区间里选数的话,我们把选出来的数减去选好之后对应的下标,发现得到的数就来自于原来的([L,R]),于是就变成了从(R+n-L-1+1=n+m-1)里选择的(n)个数,就是(inom{n+m-1}{n})

    也可以这样理解,视为把(n)个小球放到(m)个盒子里,这样的话多个小球可以放到同一个盒子里,就对应着一个数可以被选择多次,盒子也可以是空着的,对应着一个数可以不被选择,根据插板法,这样的方案数就是(inom{n+m-1}{m-1}=inom{n+m-1}{n})

    现在的问题变成了求

    [sum_{i=1}^{n}inom{i+m-1}{m-1} ]

    之后画一下柿子就是(inom{n+m}{m}=inom{n+m}{n})

    之后上(Lucas)就好了

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #define LL long long
    #define re register
    #define maxn 1000005
    const LL mod=1000003;
    inline int read()
    {
    	char c=getchar();
    	int x=0;
    	while(c<'0'||c>'9') c=getchar();
    	while(c>='0'&&c<='9')
    		x=(x<<3)+(x<<1)+c-48,c=getchar();
    	return x;
    }
    LL fac[maxn],inv[maxn];
    inline LL C(LL n,LL m)
    {
    	if(!m) return 1;
    	if(!n) return 0;
    	if(n==m) return 1;
    	if(m>n) return 0;
    	return fac[n]*inv[fac[m]*fac[n-m]%mod]%mod;
    }
    LL Lucas(LL n,LL m)
    {
    	if(!m) return 1;
    	if(!n) return 0;
    	if(n<mod&&m<mod) return C(n,m);
    	return C(n%mod,m%mod)*Lucas(n/mod,m/mod)%mod;
    }
    int n,m,T,L,R;
    int main()
    {
    	T=read();
    	fac[0]=1;
    	for(re int i=1;i<=mod;i++) fac[i]=fac[i-1]*i%mod;
    	inv[1]=1;
    	for(re int i=2;i<=mod;i++) inv[i]=(mod-mod/i)*inv[mod%i]%mod;
    	while(T--)
    	{
    		n=read(),L=read(),R=read();
    		m=R-L+1;
    		printf("%lld
    ",(Lucas(n+m,m)-1+mod)%mod);
    	}
    	return 0;
    }
    
  • 相关阅读:
    [buuctf] pwn-第五空间2019pwn
    [buuctf] pwn-[OGeek2019]babyrop
    [buuctf] pwn-ciscn_2019_c_1
    [buuctf] pwn-jarvisoj_level0
    wamp集成环境配置php7.x连接mssql
    EXCEL小技巧之单击单元格实现自增
    Asuhe博客转移
    数据链路层中的最小帧长是如何计算出来的?
    CSMA/CD协议中如何确定数据重传时机?
    Cache设计
  • 原文地址:https://www.cnblogs.com/asuldb/p/10205701.html
Copyright © 2011-2022 走看看