bzoj 3027: [Ceoi2004]Sweet【生成函数+组合数学】

首先根据生成函数的套路,这个可以写成:

\[
\prod_{i=1}^{n}(1+x^1+x^2+...+x^{c[i]})
\]

然后化简

\[
=\prod_{i=1}^{n}\frac{1-x^{c[i]+1}}{1-x}
\]

\[
=\prod_{i=1}^{n}\frac{1}{1-x}*(1-x^{c[i]+1})
\]

\[
=(1+x^1+x^2+...)^n*\prod_{i=1}^{n}(1-x^{c[i]+1})
\]

位数过多所以只考虑有常数项的位,后面那个式子可以dfs,然后对于得到的有常数项a的一位b,需要乘\( (1+x^1+x^2+...)^n \),然后这个式子展开后每一项的常数项是\( C_{n+i-1}^{n-1} \),也就是对于这一位方案数(常数项)的统计就是\( k*(C_{n+0-1}^{n-1}+C_{n+1-1}^{n-1}+...+C_{n+(m-b)-1}^{n-1}) \)这里无穷项变有穷是因为m的个数限制,然后后面那个组合数式子是杨辉三角的一列,找规律发现化简可得 \( C_{n+(m-b)}^{n} \),这里mod不是质数所以逆元不行,但是注意到n-m很小,所以先把n!和(n-m)!化简最后再除以m!即可

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
const int N=15,mod=2004;
int n,l,r,c[N],ans;
long long fac=1;
int C(int n,int m)
{
    if(n<m)
        return 0;
    long long ans=1,p=fac*mod;
    for(int i=n-m+1;i<=n;i++)
        ans=1ll*i%p*ans%p;
    return (ans/fac)%mod;
}
int dfs(int w,int a,int b,int m)
{
    if(w==n+1)
        return a*C(n+m-b,n)%mod;
    return (dfs(w+1,a,b,m)+dfs(w+1,-a,b+c[w]+1,m))%mod;
}
int main()
{
    scanf("%d%d%d",&n,&l,&r);
    for(int i=1;i<=n;i++)
        scanf("%d",&c[i]),fac*=i;
    printf("%d\n",((dfs(1,1,0,r)-dfs(1,1,0,l-1))%mod+mod)%mod);
    return 0;
}

原文地址:https://www.cnblogs.com/lokiii/p/10017548.html

时间: 2024-08-25 07:51:53

bzoj 3027: [Ceoi2004]Sweet【生成函数+组合数学】的相关文章

bzoj 3027: [Ceoi2004]Sweet (生成函数)

题目传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=3027. 题目大意:有$n$种数,每种有$C_i$个,问你在这些数中取出$[l,r]$个,问你有多少种不同的取法,答案对2004取模. 数据范围:$n≤10$,$C_i≤10^6$,$1≤l<r≤10^7$. 我们不妨设$f(n)$表示不超过$n$的数的取法之和. 则答案显然为$f(r)-f(l-1)$,下面来推导f(x). 显然,$f(m)$等于多项式$\Pi_{i=1}^{n} \

[BZOJ3027][Ceoi2004]Sweet 容斥+组合数

3027: [Ceoi2004]Sweet Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 135  Solved: 66[Submit][Status][Discuss] Description John得到了n罐糖果.不同的糖果罐,糖果的种类不同(即同一个糖果罐里的糖果种类是相同的,不同的糖果罐里的糖果的种类是不同的).第i个糖果罐里有 mi个糖果.John决定吃掉一些糖果,他想吃掉至少a个糖果,但不超过b个.问题是John 无法确定吃多少个糖果

BZOJ 1005 明明的烦恼 (组合数学)

题解:n为树的节点数,d[ ]为各节点的度数,m为无限制度数的节点数. 则             所以要求在n-2大小的数组中插入tot各序号,共有种插法: 在tot各序号排列中,插第一个节点的方法有种插法: 插第二个节点的方法有种插法: ......... 另外还有m各节点无度数限制,所以它们可任意排列在剩余的n-2-tot的空间中,排列方法总数为 根据乘法原理: #include <cstdio> #include <cmath> int n,m,tot,i,j,d,down

BZOJ 3027 Sweets 生成函数,容斥

Description John得到了n罐糖果.不同的糖果罐,糖果的种类不同(即同一个糖果罐里的糖果种类是相同的,不同的糖果罐里的糖果的种类是不同的).第i个糖果罐里有 mi个糖果.John决定吃掉一些糖果,他想吃掉至少a个糖果,但不超过b个.问题是John 无法确定吃多少个糖果和每种糖果各吃几个.有多少种方法可以做这件事呢? Input 从标准输入读入每罐糖果的数量,整数a到b John能够选择的吃掉糖果的方法数(满足以上条件) Output 把结果输出到标准输出(把答案模 2004 输出)

【BZOJ 3997】 3997: [TJOI2015]组合数学 (DP| 最小链覆盖=最大点独立集)

3997: [TJOI2015]组合数学 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 919  Solved: 664 Description 给出一个网格图,其中某些格子有财宝,每次从左上角出发,只能向下或右走.问至少走多少次才能将财宝捡完.此对此问题变形,假设每个格子中有好多财宝,而每一次经过一个格子至多只能捡走一块财宝,至少走多少次才能把财宝全部捡完. Input 第一行为正整数T,代表数据组数. 每组数据第一行为正整数N,M代表网格图有

[BZOJ 3028]食物(生成函数)

Description 明明这次又要出去旅游了,和上次不同的是,他这次要去宇宙探险! 我们暂且不讨论他有多么NC,他又幻想了他应该带一些什么东西.理所当然的,你当然要帮他计算携带N件物品的方案数. 他这次又准备带一些受欢迎的食物,如:蜜桃多啦,鸡块啦,承德汉堡等等 当然,他又有一些稀奇古怪的限制: 每种食物的限制如下: 承德汉堡:偶数个 可乐:0个或1个 鸡腿:0个,1个或2个 蜜桃多:奇数个 鸡块:4的倍数个 包子:0个,1个,2个或3个 土豆片炒肉:不超过一个. 面包:3的倍数个 注意,这里

BZOJ 3193 JLOI2013 地形生成 组合数学

题目大意:给定一些山,每座山有一个高度和一个关键值,现在要将这些山排成一个序列,要求每座山之前高度高于它的山的数量不能超过它的关键值,求合法的标号序列数和高度序列数 = = 首先我们考虑第一问 我们发现高度较小的山对高度较大的山是没有影响的 那么我们可以将山按照高度从大到小排序 每座山插入时都有一些备选位置 将备选位置数相乘即是答案 现在考虑第二问 嘲讽:谁能告诉我O(n^3)到底怎么做= = 我们按照之前的思路将山按照高度从大到小排序 将高度相同的山拎出来 每一座山都有一些位置可选 那么我们不

BZOJ 3505 CQOI2014 数三角形 组合数学

题目大意: 给定一个m*n的方格.求上面有多少个格点三角形 m,n<=1000 枚举O(m^3*n^3).铁定超时 我们选择补集法 首先我们随意选择三个不反复的点构成三角形 用组合数算出这一值 然后刨除三点一线的点就可以 枚举三点之中在两边的点的横纵坐标之差,中间点的位置数为GCD(x,y)-1,统计答案就可以 注意初始计算组合数时可能会爆int #include<cstdio> #include<cstring> #include<iostream> #incl

[BZOJ 4767]两双手(组合数学+Dp)

Description 老W是个棋艺高超的棋手,他最喜欢的棋子是马,更具体地,他更加喜欢马所行走的方式.老W下棋时觉得无聊,便 决定加强马所行走的方式,更具体地,他有两双手,其中一双手能让马从(u,v)移动到(u+Ax,v+Ay)而另一双手能让 马从(u,v)移动到(u+Bx,v+By).小W看见老W的下棋方式,觉得非常有趣,他开始思考一个问题:假设棋盘是个无限 大的二维平面,一开始马在原点(0,0)上,若用老W的两种方式进行移动,他有多少种不同的移动方法到达点(Ex,Ey )呢?两种移动方法不