【BZOJ4003】序列统计(组合数学,卢卡斯定理)

【BZOJ4003】序列统计(组合数学,卢卡斯定理)

题面

Description

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

Input

输入第一行包含一个整数T,表示数据组数。
第2到第T+1行每行包含三个整数N、L和R,N、L和R的意义如题所述。
1≤N,L,R≤10^9,1≤T≤100,输入数据保证L≤R。

Output

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

Sample Input

2

1 4 5

2 4 5

Sample Output

2

5

题解

\(L,R\)不就是搞笑的吗?
直接向左平移\(L-1\)个单位就好了。。。
以下的\(X=R-(L-1)\)

现在,认真的来解决问题
考虑这样一道小学奥数题:
有\(n\)个相同的小球,要放进\(m\)个不同的盒子里
每个盒子可以为空,求放的方案数

先给每个盒子人为的放一个小球
再用隔板法计算
答案为\(C_{n+m-1}^{m-1}\)

现在,这个问题不就是一样的吗?
相当于有X个盒子,分别代表着X个数字
现在有\(i\)个小球,求放法总数
其中\(i\in [1,n]\)
所以,所求为:
\(\sum_{i=1}^nC_{i+X-1}^{X-1}\)
化简一下
\(C_{n+X}^X-1\)
然后卢卡斯一波就可以啦

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define MOD 1000003
#define MAX (MOD+1000)
#define ll int
ll n,L,R;
ll jc[MAX],inv[MAX];
inline int read()
{
    int x=0,t=1;char ch=getchar();
    while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
    if(ch=='-')t=-1,ch=getchar();
    while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
    return x*t;
}
ll fpow(ll a,ll b)
{
    ll s=1;
    while(b){if(b&1)s=1ll*s*a%MOD;a=1ll*a*a%MOD;b>>=1;}
    return s;
}
ll C(ll m,ll n)
{
    if(n<m)return 0;
    return 1ll*jc[n]*inv[m]%MOD*inv[n-m]%MOD;
}
ll Lucas(ll m,ll n)
{
    if(n<m)return 0;
    if(m==0)return 1;
    return (1ll*Lucas(m/MOD,n/MOD)*C(m%MOD,n%MOD))%MOD;
}
int main()
{
    int T;T=read();
    jc[0]=inv[0]=1;
    for(int i=1;i<MOD;++i)jc[i]=1ll*jc[i-1]*i%MOD;
    inv[MOD-1]=fpow(jc[MOD-1],MOD-2);
    for(int i=MOD-2;i;--i)inv[i]=1ll*inv[i+1]*(i+1)%MOD;
    while(T--)
    {
        n=read();L=read();R=read();
        R-=L-1;
        printf("%d\n",(Lucas(R,n+R)-1+MOD)%MOD);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/cjyyb/p/8232684.html

时间: 2024-08-01 05:05:24

【BZOJ4003】序列统计(组合数学,卢卡斯定理)的相关文章

【BZOJ 4403】 4403: 序列统计 (卢卡斯定理)

4403: 序列统计 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 653  Solved: 320 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

【BZOJ4403】序列统计(Lucas定理,组合计数)

题意:给定三个正整数N.L和R, 统计长度在1到N之间,元素大小都在L到R之间的单调不降序列的数量. 输出答案对10^6+3取模的结果. 对于100%的数据,1≤N,L,R≤10^9,1≤T≤100,输入数据保证L≤R. 题意:WYZ作业 L和R本身没有意义,等价于[1,R-L+1],共有R-L+1种取值方法 显然是一个阶梯状的东西 但我们直接算需要枚举长度,通分又很麻烦 考虑使用R-L填充长度不足N的区间,这样问题就转化为: 求长度为N,元素大小都在1到R-L之间的单调不降序列的数量 需要注意

bzoj 1951: [Sdoi2010]古代猪文 【中国剩余定理+欧拉定理+组合数学+卢卡斯定理】

首先化简,题目要求的是 \[ G^{\sum_{i|n}C_{n}^{i}}\%p \] 对于乘方形式快速幂就行了,因为p是质数,所以可以用欧拉定理 \[ G^{\sum_{i|n}C_{n}^{i}\%\varphi(p)} \] \[ G^{\sum_{i|n}C_{n}^{i}\%p-1} \] 因为p-1不是质数,所以把它质因数分解为2,3,4679,35617,最后用中国剩余定理合并即可. #include<iostream> #include<cstdio> using

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

BZOJ 3992: [SDOI2015]序列统计 NTT+快速幂

3992: [SDOI2015]序列统计 Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 1155  Solved: 532[Submit][Status][Discuss] Description 小C有一个集合S,里面的元素都是小于M的非负整数.他用程序编写了一个数列生成器,可以生成一个长度为N的数列,数列中的每个数都属于集合S. 小C用这个生成器生成了许多这样的数列.但是小C有一个问题需要你的帮助:给定整数x,求所有可以生成出的,且满足数列中

cf451E Devu and Flowers 卢卡斯定理+容斥定理

题目:http://codeforces.com/problemset/problem/451/E 题意:有n个盒子(n<=20),每个盒子中有10^12个小球,现从每个盒子中取出若干球(可为0),求共取出s个小球(s<=10^14)的方案数. 组合数学问题,求C(n,m).但n,m过大时,可用卢卡斯定理. 卢卡斯定理:C(n,m) %p = C(n/p,m/p) * C(n%p,m%p) 从n个盒子中取出s个球的方案数,相当于插板,即 C(s+n-1,n-1).注意这是没有限制条件的情况.

BZOJ 3992 【SDOI2015】 序列统计

题目链接:序列统计 我来复习板子了--这道题也是我写的第一发求原根啊? 求原根方法: 从小到大依次枚举原根.设当前枚举的原根为\(x\),模数为\(p\),\(p-1\)的质因数分别为\(p_1,p_2,\dots,p_m\),则只需检验\(x^{\frac{p}{p_i}}\equiv1 \pmod{p}\)是否成立即可.如果成立则\(x\)不是原根. 然后这道题朴素\(dp\)就不讲了.设\(m\)的原根为\(g\),那么把每个数表示成\(g^k\)的形式就可以乘法变加法了,就成为了\(NT

卢卡斯定理的模板以及应用

定义: Lucas定理是用来求 C(n,m) MOD p,p为素数的值.Lucas定理:我们令n=sp+q,m=tp+r.(q,r≤p) 那么:(在编程时你只要继续对 调用 Lucas 定理即可.代码可以递归的去完成这个过程,其中递归终点为 t=0 :时间复杂度 O(logp(n)?p):) 主要解决当 n,m 比较大的时候,而 p 比较小的时候 <1e6 ,那么我们就可以借助 卢卡斯定理来解决这个问题: 模板: #include <iostream> #include <cstd

不要搜索,出栈序列统计

1627: 出栈序列统计 时间限制: 1 Sec  内存限制: 128 MB 题目描述 栈是常用的一种数据结构,有n令元素在栈顶端一侧等待进栈,栈顶端另一侧是出栈序列.你已经知道栈的操作有两·种:push和pop,前者是将一个元素进栈,后者是将栈顶元素弹出.现在要使用这两种操作,由一个操作序列可以得到一系列的输出序列.请你编程求出对于给定的n,计算并输出由操作数序列1,2,-,n,经过一系列操作可能得到的输出序列总数. 输入 一个整数n(1<=n<=15) 输出 一个整数,即可能输出序列的总数