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. Scratch不仅适合小朋友,程序员和大学老师都应该广泛使用!!!

    去年接触到了Scratch这个编程工具,它是一种简易图形化编程工具,这个软件的开发团队来自于麻省理工大学称为“终身幼儿园团队”(Lifelong Kindergarten Group). 网址http ...

  2. DisplayAttribute没作用,why?

    namespace WebBulletinBoard.DataAccess { using System; using System.ComponentModel.DataAnnotations; u ...

  3. Lodop的TABLE中format格式化的使用

    LODOP中的ADD_PRINT_TABLE支持很多函数和计算方法,可以用tdata对table表格里额数据进行计算,用format对结果进行格式化.这个format只能和tdata搭配使用,不能单独 ...

  4. Active Directory: LDAP Syntax Filters

    LDAP syntax filters can be used in many situations to query Active Directory. They can be used in VB ...

  5. HDU 2571 命运(简单dp)

    传送门 真是刷越多题,越容易满足.算是一道很简单的DP了.终于可以自己写出来了. 二维矩阵每个点都有一个幸运值,要求从左上走到右下最多能积累多少幸运值. 重点就是左上右下必须都踩到. dp[i][j] ...

  6. BZOJ5341[Ctsc2018]暴力写挂——边分治+虚树+树形DP

    题目链接: CSTC2018暴力写挂 题目大意:给出n个点结构不同的两棵树,边有边权(有负权边及0边),要求找到一个点对(a,b)满足dep(a)+dep(b)-dep(lca)-dep'(lca)最 ...

  7. 【XSY2903】B 莫比乌斯反演

    题目描述 有一个\(n\times n\)的网格,除了左下角的格子外每个格子的中心里都有一个圆,每个圆的半径为\(R\),问你在左下角的格子的中心能看到多少个圆. \(n\leq {10}^9,R_0 ...

  8. centos2.6.18升级到2.6.39

    本来想升级到最新版本4.6的,但是不成功,即使3.4也不成功,暂且先升级到2.x最新版本. 步骤如下: 一 下载源码 https://www.kernel.org/pub/linux/kernel/ ...

  9. mysql慢查询日志按天切割归纳

    问题描述: mysql开启慢查询功能,再正常不过,那么存在这样一种情况:慢查询写入的文件位置和文件名是指定好的,如果慢查询时间设定严苛,不出意外,记录慢查询的单个文件大小会日益增大,几十兆或者上百兆, ...

  10. 微信小程序之动态获取元素宽高

    我以前一直以为微信小程序不能动态获取view元素的宽高.但是自从看到: wx.createSelectorQuery() 这个api接口,以前的某些问题就能得到解决了... 那么,这个api接口怎么用 ...