题解-CodeChef IOPC14L Sweets Problem
Problem
题目概要:给定 \(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\) 颗糖果的种类有多少,则
\]
这个东西的复杂度是 \(O(S^2\log S\log n)\) 的,照理说已经比较优了,但还可以继续优化
考虑到
\]
所以上面的式子可以化为
\]
\]
上式中的分子由于每一项都是二项式的幂次,最终的答案可以利用Dp在 \(O(AS\ln S)\) 的时间内求得(其中\(\ln S\)为级数求和复杂度)
至于分母,视作 \((x-1)^{-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的更多相关文章
- 【题解】CF45G Prime Problem
[题解]CF45G Prime Problem 哥德巴赫板子题? \(\frac{n(n+1)}{2}\)若是质数,则不需要分了. 上式 若是奇数,那么拆成2和另一个数. 上式 若是偶数吗,直接\(O ...
- 【题解】P4137 Rmq Problem(莫队)
[题解]P4137 Rmq Problem(莫队) 其实这道题根本就不用离散化! 因为显然有\(mex\)值是\(\le 2\times 10^5\)的,所以对于大于\(2\times 10^5\)的 ...
- 题解西电OJ (Problem 1006 - 转盘游戏)--动态规划
题目链接 : http://acm.xidian.edu.cn/land/problem/detail?problem_id=1006 Description wm最近喜欢上一种无聊的转盘解锁游戏,他 ...
- 【题解】An Easy Problem
题目描述 给定一个正整数N,求最小的.比N大的正整数M,使得M与N的二进制表示中有相同数目的1. 举个例子,假如给定的N为78,其二进制表示为1001110,包含4个1,那么最小的比N大的并且二进制表 ...
- [题解]UVA10026 Shoemaker's Problem
链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&am ...
- [题解] [AGC024F] Simple Subsequence Problem
题目大意 有一个 01 串集合 \(S\),其中每个串的长度都不超过 \(N\),你要求出 \(S\) 中至少是 \(K\) 个串的子序列的最长串,如果有多解,输出字典序最小的那组解. 由于 \(S\ ...
- 题解西电OJ (Problem 1007 -做一名正气的西电人 )--长整型计算
Description 一天,wm和zyf想比比谁比较正气,但正气这种东西无法量化难以比较,为此,他们想出了一个方法,两人各写一个数字,然后转化为二进制,谁的数字中二进制1多谁就比较正气! Input ...
- 题解西电OJ (Problem 1005 -跳舞毯)--动态规划
Description zyf不小心得了一种怪病,为了维持一天的精力他必须不停跳动.于是他买了一条跳舞毯,每天跳上几小时.众所周知,跳舞毯是给定一个序列,让你在指定时间踏指定的按钮,但zyf似乎不怎么 ...
- 题解西电OJ (Problem 1004 -亚特兰提斯)--最小生成树
Description 为了找寻沉睡的亚特兰提斯大陆,wm来到了大西洋上进行探险,找了半个月仍一无所获.然而在一次突袭而来的暴风雨后,wm的船莫名地驶入了一片未知的区域,发现了一个地图上未标记的岛屿, ...
随机推荐
- 【Topcoder 1879】Scheduling
题意:给一个\(dag\),每一个点有一个访问时间. 现在可以同时访问两个点,但当连向这个点的所有点都被访问完成后才可以访问这个点. 问最短访问时间. 思路:一眼贪心.可惜是错的. 第二眼暴搜.就这么 ...
- C#/.NET基于Topshelf创建Windows服务程序及服务的安装和卸载(极速,简洁)
本文首发于:码友网--一个专注.NET/.NET Core开发的编程爱好者社区. 文章目录 C#/.NET基于Topshelf创建Windows服务的系列文章目录: C#/.NET基于Topshelf ...
- Python学习--Python运算符
什么是运算符? 举个简单的例子 4 + 5 = 9 . 例子中,4 和 5 被称为操作数,"+" 称为运算符. Python语言支持以下类型的运算符: 算数运算符 比较(关系)运算 ...
- Linux下Power Management开发总结
本文作为一个提纲挈领的介绍性文档,后面会以此展开,逐渐丰富. 1. 前言 在 <开发流程>中介绍了PM开发的一般流程,重点是好的模型.简单有效的接口参数.可量化的测试环境以及可独性强的输出 ...
- Socket之listen() receive()
socket.listen([backlog]) 相比listen方法,它俩就好理解多了,一个是Client用于连接Server的方法,一个是Server用于接收Client的连接申请的方法. 但事 ...
- 一个方法教你认识ref(简单易懂)
参数分为值类型和引用类型,当我们将一个值类型的参数进行传递到另一个方法的时候相当于,将这个变量进行复制到该方法进行操作,但是不会对该变量原始的值有影响. 但是有时候我们需要他有“影响”于是ref就出现 ...
- idea2018.3.5永久破解教程
视频教程地址: http://v.youku.com/v_show/id_XNDEwNDU1NjQ4MA==.html 配套笔记: ①修改配置文件 -Xms128m -Xmx750m -XX:Rese ...
- Django之ORM
- delete *p可以替代delete[] p吗?
在stackoverflow看到一个标题描述的问题,问题链接是:https://stackoverflow.com/questions/55524140/is-delete-p-an-alternat ...
- ABP项目启动及源代码结构
在整体介绍ABP项目之前我们需要从官方网站下载模板项目,下载以后放到一个本地目录下,启动VS打开源代码.具体下载的步骤如下: 一 创建ABP项目模板 1 进入官方网站然后选择特定的样板项目. 2 ...