Problem

CodeChef-IOPC14L

题目概要:给定 \(n\) 种糖果且给定每种糖果的数量 \(A_i\),\(Q\) 组询问,每次问选出 \(S\) 个糖果的方案数(模\(10^9+7\))

\(n\leq 10^6,A_i\leq 10^3,Q\leq 10^4,S\leq 2\times 10^3\)

Solution

都说这题是容斥,但是始终不知道如何容斥,下面介绍一个母函数的做法

这题想暴力首先可以想到将所有糖果的母函数乘起来。形式化的,对于一种糖果若有 \(t\) 个,则其母函数为 \(\sum_{i=0}^tx^i\),将所有共 \(n\) 个母函数乘起来得到的\(x^S\)对应的系数即为答案

问题转化为求所有母函数的积,设为 \(F\)

考虑到 \(n\leq 10^6\),暴力求积复杂度为 \(O(nS\log S)\),但\(A_i\leq 10^3\),则考虑可以将本质相同的糖果合并一下,可以得出 \(s[x]\) 表示有 \(x\) 颗糖果的种类有多少,则

\[F=\prod_{i=1}^{2000}(\sum_{j=0}^ix^j)^{s[i]}
\]

这个东西的复杂度是 \(O(S^2\log S\log n)\) 的,照理说已经比较优了,但还可以继续优化

考虑到

\[\sum_{i=0}^nx^i=\frac {x^{n+1}-1}{x-1}
\]

所以上面的式子可以化为

\[F=\prod_{i=1}^{2000}(\frac {x^{i+1}-1}{x-1})^{s[i]}
\]

\[F=\frac {\prod_{i=1}^{2000}(x^{i+1}-1)^{s[i]}}{(x-1)^n}
\]

上式中的分子由于每一项都是二项式的幂次,最终的答案可以利用Dp在 \(O(AS\ln S)\) 的时间内求得(其中\(\ln S\)为级数求和复杂度)

至于分母,视作 \((x-1)^{-n}\),可以考虑

\[(1-x)^{-1}=\frac 1{1-x}=\sum_{i=0}^{+\infty}x^i
\]

\[(x-1)^{-n}=(-1)^n(1-x)^{-n}=(-1)^n(\frac 1{1-x})^n=(-1)^n(\sum_{i=0}^{+\infty}x^i)^n
\]

发现那个 \((-1)^n\) 很讨厌,于是将原式 \(F\) 的分母分子同时乘一个 \((-1)^n\),由于 \(\sum s[i]=n\),所以分子变为 \(\prod_{i=1}^{2000}(1-x^{i+1})^{s[i]}\),同样可以利用Dp在 \(O(AS\ln S)\) 的时间内求得

继续考虑分母,现在已经求得分母倒数为 \((\sum_{i=0}^{+\infty}x^i)^n\),这个式子中 \(x^k\) 的项系数等价于将 \(k\) 分解为 \(n\) 个非负整数和的方案数,即\(\binom {n+k-1}{k}\)

统计答案只需要分子与分母倒数做卷积即可,时间复杂度 \(O(n+AS\ln S+S^2)\)

Code

另外,这道题不支持c++提交,整的我交了好多次才知道 c 与 c++ 的不同(比如说不能用取址符、不能用 const 定义出的数字去定义数组大小等)

#include <stdio.h>
#include <ctype.h>
typedef long long ll; inline int read(){
char c11=getchar();int x = 0;
while(!isdigit(c11))c11=getchar();
while(isdigit(c11))x=x*10+c11-'0',c11=getchar();
return x;
} //const int N = 2001, M = 2001000, p = 1000000007;
const int p = 1000000007;
#define N 2001
#define M 2001000
int fac[M],inv[M],s[N];
int f[N][N],Ans[N];
int n; inline int qpow(int A,int B){
int res = 1;while(B){
if(B&1) res = (ll)res * A%p;
A = (ll)A * A%p, B >>= 1;
}return res;
} inline int c(int nn,int mm){return (ll)fac[nn]*inv[mm]%p*inv[nn-mm]%p;} int main() {
fac[0] = f[0][0] = 1;
for(int i=1;i<M;++i) fac[i] = (ll)fac[i-1]*i%p;
inv[M-1] = qpow(fac[M-1],p-2);
for(int i=M-1;i;--i) inv[i-1] = (ll)inv[i]*i%p; n = read();
for(int i=1;i<=n;++i)++s[read()]; for(int i=1;i<N;++i)
for(int j=0,t;j<=s[i] && (t = (i+1)*j)<N;++j)
if(j&1) for(int k=0;k+t<N;++k)
f[i][k+t] = (f[i][k+t] + (ll)c(s[i],j) * f[i-1][k]%p*(p-1))%p;
else for(int k=0;k+t<N;++k)
f[i][k+t] = (f[i][k+t] + (ll)c(s[i],j) * f[i-1][k])%p; for(int i=0;i<N;++i)
s[i] = c(n+i-1,i); for(int i=0;i<N;++i)
for(int j=0;j<=i;++j)
Ans[i] = (Ans[i] + (ll)f[N-1][j] * s[i-j])%p; int Q = read();
while(Q--) printf("%d\n",Ans[read()]);
return 0;
}

题解-CodeChef IOPC14L Sweets Problem的更多相关文章

  1. 【题解】CF45G Prime Problem

    [题解]CF45G Prime Problem 哥德巴赫板子题? \(\frac{n(n+1)}{2}\)若是质数,则不需要分了. 上式 若是奇数,那么拆成2和另一个数. 上式 若是偶数吗,直接\(O ...

  2. 【题解】P4137 Rmq Problem(莫队)

    [题解]P4137 Rmq Problem(莫队) 其实这道题根本就不用离散化! 因为显然有\(mex\)值是\(\le 2\times 10^5\)的,所以对于大于\(2\times 10^5\)的 ...

  3. 题解西电OJ (Problem 1006 - 转盘游戏)--动态规划

    题目链接 : http://acm.xidian.edu.cn/land/problem/detail?problem_id=1006 Description wm最近喜欢上一种无聊的转盘解锁游戏,他 ...

  4. 【题解】An Easy Problem

    题目描述 给定一个正整数N,求最小的.比N大的正整数M,使得M与N的二进制表示中有相同数目的1. 举个例子,假如给定的N为78,其二进制表示为1001110,包含4个1,那么最小的比N大的并且二进制表 ...

  5. [题解]UVA10026 Shoemaker's Problem

    链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&am ...

  6. [题解] [AGC024F] Simple Subsequence Problem

    题目大意 有一个 01 串集合 \(S\),其中每个串的长度都不超过 \(N\),你要求出 \(S\) 中至少是 \(K\) 个串的子序列的最长串,如果有多解,输出字典序最小的那组解. 由于 \(S\ ...

  7. 题解西电OJ (Problem 1007 -做一名正气的西电人 )--长整型计算

    Description 一天,wm和zyf想比比谁比较正气,但正气这种东西无法量化难以比较,为此,他们想出了一个方法,两人各写一个数字,然后转化为二进制,谁的数字中二进制1多谁就比较正气! Input ...

  8. 题解西电OJ (Problem 1005 -跳舞毯)--动态规划

    Description zyf不小心得了一种怪病,为了维持一天的精力他必须不停跳动.于是他买了一条跳舞毯,每天跳上几小时.众所周知,跳舞毯是给定一个序列,让你在指定时间踏指定的按钮,但zyf似乎不怎么 ...

  9. 题解西电OJ (Problem 1004 -亚特兰提斯)--最小生成树

    Description 为了找寻沉睡的亚特兰提斯大陆,wm来到了大西洋上进行探险,找了半个月仍一无所获.然而在一次突袭而来的暴风雨后,wm的船莫名地驶入了一片未知的区域,发现了一个地图上未标记的岛屿, ...

随机推荐

  1. AT24 I2C EEPROM解析及测试

    关键词:AT24.I2C.nvmem.EEPROM. 1. AT24C介绍 AT24C是一款采用I2C通信的EEPROM,相关驱动涉及到I2C和nvmem. I2C是读写数据的通道,nvmem将AT2 ...

  2. 自己编写 EntityTypeConfiguration

    1.新建类库 EFCore.EntityTypeConfig ,安装nuget  PM> Install-Package Microsoft.EntityFrameworkCore 2.新建接口 ...

  3. JDK1.8源码(九)——java.util.LinkedHashMap 类

    前面我们介绍了 Map 集合的一种典型实现 HashMap ,关于 HashMap 的特性,我们再来复习一遍: ①.基于JDK1.8的HashMap是由数组+链表+红黑树组成,相对于早期版本的 JDK ...

  4. System.IO在不存在的路径下创建文件夹和文件的测试

    本文测试System.IO命名空间下的类,在不存在的路径下创建文件夹和文件的效果: 首先测试创建文件夹: System.IO.Directory.CreateDirectory(@"C:\A ...

  5. 开发工具IntelliJ IDEA的安装步骤及首次启动和创建项目

    开发工具IDEA概述 DEA是一个专门针对Java的集成开发工具(IDE),由Java语言编写.所以,需要有JRE运行环境并配置好环境变量.它可以极大地提升我们的开发效率.可以自动编译,检查错误.在公 ...

  6. JMeter配置好环境变量后无法启动---翻车笔记

    双击jmeter.bat出现下图情况 手欠了win7中配置 path无意中多删了变量 解决方法:在计算机-属性-高级系统设置-环境变量Path中添加 %SystemRoot%/system32;%Sy ...

  7. 7.docker日志收集

    默认情况下,docker logs或者docker service logs显示命令的输出,就像在终端中以交互方式运行命令时一样.UNIX和Linux命令通常开在运行时间上三个I / O流,所谓的 S ...

  8. BZOJ 2200 道路与航线 (算竞进阶习题)

    dijkstra + 拓扑排序 这道题有负权边,但是卡了spfa,所以我们应该观察题目性质. 负权边一定是单向的,且不构成环,那么我们考虑先将正权边连上.然后dfs一次找到所有正权边构成的联通块,将他 ...

  9. pycharm项目上传到Github

    使用本地代码直接share到github上过程中出现了一个问题: Successfully created project 'xxx' on GitHub, but initial push fail ...

  10. n98-magerun2.phar

    installl: 1,cd /usr/local/bin && curl -O https://files.magerun.net/n98-magerun2.phar 2,chmod ...