题目背景

付公主有一个可爱的背包qwq

题目描述

这个背包最多可以装10^5105大小的东西

付公主有n种商品,她要准备出摊了

每种商品体积为Vi,都有10^5105件

给定m,对于s\in [1,m]s∈[1,m],请你回答用这些商品恰好装s体积的方案数

输入输出格式

输入格式:

第一行n,m

第二行V1~Vn

输出格式:

m行,第i行代表s=i时方案数,对998244353取模

输入输出样例

输入样例#1:

  1. 2 4
  2. 1 2

输出样例#1:

  1. 1
  2. 2
  3. 2
  4. 3

说明

对于30%的数据,n<=3000,m<=3000

对于60%的数据,纯随机生成

对于100%的数据, n<=100000,m<=100000

对于100%的数据,Vi<=m


思路

首先我们得到这道题是n个形如\(\sum_{i=0}^{\infin}x^{vi}\)的生成函数的乘积,然后考虑优化

因为这里个数的上限是\(1e5\)可以看做无限大

所以我们可以得到

\[f(x)=\sum_{i=0}x^{vi}=\frac{1}{1-x^{v}}
\]

然后因为直接多项式相乘非常麻烦

考虑取ln之后相加

\[g(x)=ln(f(x))
\]

求一波导数

\[g'(x)=\frac{f'(x)}{f(x)}=(1-x^v)\sum_{i=1}vi*x^{vi-1}
\]

然后把\((1-x^v)\)展开变成

\[g'(x)=\sum_{i=1}v*x^{vi-1}
\]

所以

\[g(x)=\sum_{i=1}\frac{1}{i}x^{vi}
\]

这样的话多项式的有效项数和是一个调和级数

所以多项式加\(\O(n\log n)\)

然后exp回去


  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. int read() {
  4. int res = 0; char c = getchar();
  5. while (!isdigit(c)) c = getchar();
  6. while (isdigit(c)) res = (res << 1) + (res << 3) + c - '0', c = getchar();
  7. return res;
  8. }
  9. typedef long long ll;
  10. typedef vector<int> Poly;
  11. const int N = 3e5 + 10;
  12. const int Mod = 998244353;
  13. const int G = 3;
  14. int add(int a, int b, int mod = Mod) {
  15. return (a += b) >= mod ? a - mod : a;
  16. }
  17. int sub(int a, int b, int mod = Mod) {
  18. return (a -= b) < 0 ? a + mod : a;
  19. }
  20. int mul(int a, int b, int mod = Mod) {
  21. return 1ll * a * b % mod;
  22. }
  23. int fast_pow(int a, int b, int mod = Mod) {
  24. int res = 1;
  25. for (; b; b >>= 1, a = mul(a, a, mod))
  26. if (b & 1) res = mul(res, a, mod);
  27. return res;
  28. }
  29. int w[2][N];
  30. void init() {
  31. int wn;
  32. for (int i = 1; i < (1 << 18); i <<= 1) {
  33. w[1][i] = w[0][i] = 1;
  34. wn = fast_pow(G, (Mod - 1) / (i << 1));
  35. for (int j = 1; j < i; j++)
  36. w[1][i + j] = mul(wn, w[1][i + j - 1]);
  37. wn = fast_pow(G, Mod - 1 - (Mod - 1) / (i << 1));
  38. for (int j = 1; j < i; j++)
  39. w[0][i + j] = mul(wn, w[0][i + j - 1]);
  40. }
  41. }
  42. void transform(int *t, int len, int typ) {
  43. for (int i = 0, j = 0, k; j < len; j++) {
  44. if (j > i) swap(t[i], t[j]);
  45. for (k = (len >> 1); k & i; k >>= 1) i ^= k;
  46. i ^= k;
  47. }
  48. for (int i = 1; i < len; i <<= 1) {
  49. for (int j = 0; j < len; j += (i << 1)) {
  50. for (int k = 0; k < i; k++) {
  51. int x = t[j + k], y = mul(w[typ][i + k], t[i + j + k]);
  52. t[j + k] = add(x, y);
  53. t[j + k + i] = sub(x, y);
  54. }
  55. }
  56. }
  57. if (typ) return;
  58. int inv = fast_pow(len, Mod - 2);
  59. for (int i = 0; i < len; i++)
  60. t[i] = mul(t[i], inv);
  61. }
  62. void print(Poly a) {
  63. for (size_t i = 0; i < a.size(); i++) {
  64. cout<<a[i]<<" ";
  65. }cout<<endl;
  66. }
  67. void clean(Poly &a) {
  68. while (a.size() && !a.back())
  69. a.pop_back();
  70. }
  71. Poly add(Poly a, Poly b) {
  72. a.resize(max(a.size(), b.size()));
  73. for (size_t i = 0; i < b.size(); i++)
  74. a[i] = add(a[i], b[i]);
  75. return a;
  76. }
  77. Poly sub(Poly a, Poly b) {
  78. a.resize(max(a.size(), b.size()));
  79. for (size_t i = 0; i < b.size(); i++)
  80. a[i] = sub(a[i], b[i]);
  81. return a;
  82. }
  83. Poly mul(const Poly &a, const Poly &b) {
  84. int len = a.size() + b.size() + 1;
  85. len = 1 << (int) ceil(log2(len));
  86. static Poly prea, preb;
  87. prea = a;
  88. preb = b;
  89. prea.resize(len);
  90. preb.resize(len);
  91. transform(&prea[0], len, 1);
  92. transform(&preb[0], len, 1);
  93. for (int i = 0; i < len; i++)
  94. prea[i] = mul(prea[i], preb[i]);
  95. transform(&prea[0], len, 0);
  96. clean(prea);
  97. return prea;
  98. }
  99. Poly inv(Poly a, int n) {
  100. if (n == 1) return Poly(1, fast_pow(a[0], Mod - 2));
  101. int len = 1 << ((int) ceil(log2(n)) + 1);
  102. Poly x = inv(a, (n + 1) >> 1), y;
  103. x.resize(len);
  104. y.resize(len);
  105. for (int i = 0; i < n; i++)
  106. y[i] = a[i];
  107. transform(&x[0], len, 1);
  108. transform(&y[0], len, 1);
  109. for (int i = 0; i < len; i++)
  110. x[i] = mul(x[i], sub(2, mul(x[i], y[i])));
  111. transform(&x[0], len, 0);
  112. x.resize(n);
  113. return x;
  114. }
  115. Poly inv(Poly a) {
  116. return inv(a, a.size());
  117. }
  118. Poly deri(Poly a) {
  119. int n = a.size();
  120. for (int i = 1; i < n; i++)
  121. a[i - 1] = mul(a[i], i);
  122. a.resize(n - 1);
  123. return a;
  124. }
  125. Poly inte(Poly a) {
  126. int n = a.size();
  127. a.resize(n + 1);
  128. for (int i = n; i >= 1; i--)
  129. a[i] = mul(a[i - 1], fast_pow(i, Mod - 2));
  130. a[0] = 0;
  131. return a;
  132. }
  133. Poly ln(Poly a) {
  134. int len = a.size();
  135. a = inte(mul(deri(a), inv(a)));
  136. a.resize(len);
  137. return a;
  138. }
  139. Poly exp(Poly a, int n) {
  140. if (n == 1) return Poly(1, 1);
  141. Poly x = exp(a, (n + 1) >> 1), y;
  142. x.resize(n);
  143. y = ln(x);
  144. for (int i = 0; i < n; i++)
  145. y[i] = sub(a[i], y[i]);
  146. y[0]++;
  147. x = mul(x, y);
  148. x.resize(n);
  149. return x;
  150. }
  151. Poly exp(Poly a) {
  152. return exp(a, a.size());
  153. }
  154. int n, m, cnt[N], invf[N];
  155. int main() {
  156. init();
  157. n = read(), m = read();
  158. for (int i = 1; i <= n; i++)
  159. cnt[read()]++;
  160. Poly a(m + 1);
  161. for (int i = 1; i <= m; i++) invf[i] = fast_pow(i, Mod - 2);
  162. for (int i = 1; i <= m; i++) if (cnt[i]) {
  163. for (int j = i; j <= m; j += i) {
  164. a[j] = add(a[j], mul(invf[j / i], cnt[i]));
  165. }
  166. }
  167. clean(a);
  168. a = exp(a);
  169. a.resize(m + 1);
  170. for (int i = 1; i <= m; i++)
  171. printf("%d\n", a[i]);
  172. return 0;
  173. }

LuoguP4389 付公主的背包【生成函数+多项式exp】的更多相关文章

  1. 洛谷P4389 付公主的背包--生成函数+多项式

    题目链接戳这里 题目描述 有\(n\)件不同的商品,每件物品都有无限个,输出总体积为\([1,m]\)的方案数 思路 直接跑背包有\(30\) 考虑把每个物品的生成函数设出来,对于一件体积为\(v\) ...

  2. luoguP4389 付公主的背包 多项式exp

    %%%dkw 话说这是个论文题来着... 考虑生成函数\(OGF\) 对于价值为\(v\)的物品,由于有\(10^5\)的件数,可以看做无限个 那么,其生成函数为\(x^0 + x^{v} + x^{ ...

  3. [题解] LuoguP4389 付公主的背包

    这个题太神辣- 暴力背包就能获得\(30\)分的好成绩...... \(60\)分不知道咋搞..... 所以直接看\(100\)分吧\(QwQ\) 用一点生成函数的套路,对于一个体积为\(v\)的物品 ...

  4. 洛谷P4389 付公主的背包 [生成函数,NTT]

    传送门 同样是回过头来发现不会做了,要加深一下记忆. 思路 只要听说过生成函数的人相信第一眼都可以想到生成函数. 所以我们要求 \[ ans=\prod \sum_n x^{nV}=\prod \fr ...

  5. luoguP4389 付公主的背包

    luogu 显然这是个背包题 显然物品的数量是不用管的 所以考虑大小为\(v\)的物品可以装的体积用生成函数表示一下 \[ f(x)=\sum_{i=0}^{+\infty}x^{vi}=\frac{ ...

  6. 洛谷 P4389 付公主的背包 解题报告

    P4389 付公主的背包 题目背景 付公主有一个可爱的背包qwq 题目描述 这个背包最多可以装\(10^5\)大小的东西 付公主有\(n\)种商品,她要准备出摊了 每种商品体积为\(V_i\),都有\ ...

  7. Luogu4389 付公主的背包(生成函数+多项式exp)

    显然构造出生成函数,对体积v的物品,生成函数为1+xv+x2v+……=1/(1-xv).将所有生成函数乘起来得到的多项式即为答案,设为F(x),即F(x)=1/∏(1-xvi).但这个多项式的项数是Σ ...

  8. LOJ6077「2017 山东一轮集训 Day7」逆序对 (生成函数+多项式exp?朴素DP!)

    题面 给定 n , k n,k n,k ,求长度为 n n n 逆序对个数为 k k k 的排列个数,对 1 e 9 + 7 \rm1e9+7 1e9+7 取模. 1 ≤ n , k ≤ 100   ...

  9. 【Luogu4389】付公主的背包

    题目 传送门 解法 答案显然是\(n\)个形如\(\sum_{i \geq 1} x^{vi}\)的多项式的卷积 然而直接NTT的时间复杂度是\(O(nm\log n)\) 我们可以把每个多项式求\( ...

随机推荐

  1. 《剑指offer》第五题(替换空格)

    // 替换空格 // 题目:请实现一个函数,把字符串中的每个空格替换成"%20".例如输入“We are happy.”, // 则输出“We%20are%20happy.”. # ...

  2. 禁用表单元素 && 禁止选中

    一.禁用表单元素 1.dom设置属性 disabled="disabled" || disabled=true 2.css样式(高版本浏览器) pointer-events:non ...

  3. OpenGL入门程序五:三维绘制

    1.现实世界观察一个物体的时候,可能涉及到的三维变化: 1>视图变化------从不同的角度观察. 2>模型变化------移动.旋转物体,计算机中当然还可以对物体进行缩放. 3>投 ...

  4. Java基础十二--多态是成员的特点

    Java基础十二--多态是成员的特点 一.特点 1,成员变量. 编译和运行都参考等号的左边. 覆盖只发生在函数上,和变量没关系. Fu f = new Zi();System.out.println( ...

  5. R语言plot函数参数合集

    最近用R语言画图,plot 函数是用的最多的函数,而他的参数非常繁多,由此总结一下,以供后续方便查阅. plot(x, y = NULL, type = "p", xlim = N ...

  6. WPF样式——经典博客

    WPF样式博客:http://www.cnblogs.com/luluping/archive/2011/05/06/2039498.html

  7. 使用Div + CSS布局页面

    在设计网页时,能够控制好各个模块在页面中的位置是非常关键的.本章将讲解利用Div+CSS对页面元素进行定位的方法. Div是HTML中指定的专门用于布局设计的容器对象 Div是CSS布局的核心对象. ...

  8. Eclipse修改已存在的SVN地址

    1.Window---->Show View---->Other...

  9. utime修改文件的存取,修改时间

    #include <sys/types.h> #include <utime.h> int utime(const char *filename, const struct u ...

  10. SQL触发器实例(下)

    基本语法: Create Trigger [TriggerName] ON [TableName] FOR [Insert][,Delete][,Update] AS --触发器要执行的操作语句. G ...