%%%dkw

话说这是个论文题来着...

考虑生成函数\(OGF\)

对于价值为\(v\)的物品,由于有\(10^5\)的件数,可以看做无限个

那么,其生成函数为\(x^0 + x^{v} + x^{2v} + ... = \frac{1}{1 - x^v}\)

我们所需的答案即\([x^n] \prod \frac{1}{1 - x^{v_i}}\)

只需考虑求出\(A = \prod \frac{1}{1 - x^{v_i}}\)

自然地想到取对数

\(In(A) = \sum In(\frac{1}{1 - x^{v_i}})\)


不难发现

\(In(\frac{1}{1 - x^v}) = - In(1 - x^v)\)

考虑用麦克劳林级数来模拟,那么

由于\(In^{(n)}(1 - x) = - \frac{1}{(1 - x)^n} * (n - 1)!\)

\(-In(1 - x^v) = \sum \frac{x^{vi}}{i}\)

于是,我们可以直接枚举倍数,在\(O(m \log m)\)的时间内完成计算

最后只要\(O(m \log m)\)的\(exp\)一下即可


  1. #include <cmath>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <iostream>
  5. #include <algorithm>
  6. using namespace std;
  7. #define ri register int
  8. #define rep(io, st, ed) for(ri io = st; io <= ed; io ++)
  9. #define drep(io, ed, st) for(ri io = ed; io >= st; io --)
  10. #define gc getchar
  11. inline int read() {
  12. int p = 0, w = 1; char c = gc();
  13. while(c > '9' || c < '0') { if(c == '-') w = -1; c = gc(); }
  14. while(c >= '0' && c <= '9') p = p * 10 + c - '0', c = gc();
  15. return p * w;
  16. }
  17. const int sid = 500050;
  18. const int mod = 998244353;
  19. int n, m;
  20. int V[sid], F[sid], inv[sid], rev[sid], ans[sid];
  21. inline int Inc(int a, int b) { return (a + b >= mod) ? a + b - mod : a + b; }
  22. inline int Dec(int a, int b) { return (a - b < 0) ? a - b + mod : a - b; }
  23. inline int mul(int a, int b) { return 1ll * a * b % mod; }
  24. inline int fp(int a, int k) {
  25. int ret = 1;
  26. for( ; k; k >>= 1, a = mul(a, a))
  27. if(k & 1) ret = mul(ret, a);
  28. return ret;
  29. }
  30. inline void init(int Maxn, int &n, int &lg) {
  31. n = 1; lg = 0;
  32. while(n < Maxn) n <<= 1, lg ++;
  33. }
  34. inline void NTT(int *a, int n, int opt) {
  35. for(ri i = 0; i < n; i ++) if(i < rev[i]) swap(a[i], a[rev[i]]);
  36. for(ri i = 1; i < n; i <<= 1)
  37. for(ri j = 0, g = fp(3, (mod - 1) / (i << 1)); j < n; j += (i << 1))
  38. for(ri k = j, G = 1; k < i + j; k ++, G = mul(G, g)) {
  39. int x = a[k], y = mul(G, a[i + k]);
  40. a[k] = (x + y >= mod) ? x + y - mod : x + y;
  41. a[i + k] = (x - y < 0) ? x - y + mod : x - y;
  42. }
  43. if(opt == -1) {
  44. int ivn = fp(n, mod - 2);
  45. reverse(a + 1, a + n);
  46. rep(i, 0, n) a[i] = mul(a[i], ivn);
  47. }
  48. }
  49. int ia[sid], ib[sid];
  50. inline void Inv(int *a, int *b, int n) {
  51. if(n == 1) { b[0] = fp(a[0], mod - 2); return; }
  52. Inv(a, b, n >> 1);
  53. int N = 1, lg = 0; init(n + n, N, lg);
  54. for(ri i = 0; i < N; i ++)
  55. rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (lg - 1));
  56. for(ri i = 0; i < N; i ++) ia[i] = ib[i] = 0;
  57. for(ri i = 0; i < n; i ++) ia[i] = a[i], ib[i] = b[i];
  58. NTT(ia, N, 1); NTT(ib, N, 1);
  59. for(ri i = 0; i < N; i ++)
  60. ia[i] = Dec((ib[i] << 1) % mod, mul(ia[i], mul(ib[i], ib[i])));
  61. NTT(ia, N, -1);
  62. for(ri i = 0; i < n; i ++) b[i] = ia[i];
  63. }
  64. inline void Inv_init(int n) {
  65. inv[0] = inv[1] = 1;
  66. rep(i, 2, n) inv[i] = mul(inv[mod % i], mod - mod / i);
  67. }
  68. inline void wf(int *a, int *b, int n) { for(ri i = 1; i < n; i ++) b[i - 1] = mul(a[i], i); }
  69. inline void jf(int *a, int *b, int n) { for(ri i = 1; i < n; i ++) b[i] = mul(a[i - 1], inv[i]); }
  70. int iv[sid], dx[sid];
  71. inline void In(int *a, int *b, int n) {
  72. for(ri i = 0; i < n + n; i ++) iv[i] = dx[i] = 0;
  73. Inv(a, iv, n); wf(a, dx, n);
  74. int N = 1, lg = 0; init(n + n, N, lg);
  75. for(ri i = 0; i < N; i ++)
  76. rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (lg - 1));
  77. NTT(iv, N, 1); NTT(dx, N, 1);
  78. for(ri i = 0; i < N; i ++) iv[i] = mul(iv[i], dx[i]);
  79. NTT(iv, N, -1); jf(iv, b, n);
  80. }
  81. int inb[sid], fb[sid];
  82. inline void Exp(int *a, int *b, int n) {
  83. if(n == 1) { b[0] = 1; return; }
  84. Exp(a, b, n >> 1);
  85. for(ri i = 0; i < n + n; i ++) inb[i] = fb[i] = 0;
  86. In(b, inb, n);
  87. int N = 1, lg = 0; init(n + n, N, lg);
  88. for(ri i = 0; i < N; i ++)
  89. rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (lg - 1));
  90. for(ri i = 0; i < n; i ++) fb[i] = Dec(a[i], inb[i]); fb[0] ++;
  91. for(ri i = 0; i < n; i ++) inb[i] = b[i];
  92. NTT(inb, N, 1); NTT(fb, N, 1);
  93. for(ri i = 0; i < N; i ++) fb[i] = mul(fb[i], inb[i]);
  94. NTT(fb, N, -1);
  95. for(ri i = 0; i < n; i ++) b[i] = fb[i], b[i + n] = 0;
  96. }
  97. inline void calc() {
  98. int N = 1, lg = 0;
  99. init(m + 5, N, lg); Inv_init(N);
  100. for(ri i = 1; i <= m; i ++)
  101. for(ri j = i; j <= m; j += i)
  102. F[j] = Inc(F[j], mul(V[i], inv[j / i]));
  103. Exp(F, ans, N);
  104. rep(i, 1, m) printf("%d\n", ans[i]);
  105. }
  106. int main() {
  107. n = read(); m = read();
  108. rep(i, 1, n) V[read()] ++;
  109. calc();
  110. return 0;
  111. }

luoguP4389 付公主的背包 多项式exp的更多相关文章

  1. [luogu4389]付公主的背包(多项式exp)

    完全背包方案计数问题的FFT优化.首先写成生成函数的形式:对重量为V的背包,它的生成函数为$\sum\limits_{i=0}^{+\infty}x^{Vi}=\frac{1}{1-x^{V}}$于是 ...

  2. LuoguP4389 付公主的背包【生成函数+多项式exp】

    题目背景 付公主有一个可爱的背包qwq 题目描述 这个背包最多可以装10^5105大小的东西 付公主有n种商品,她要准备出摊了 每种商品体积为Vi,都有10^5105件 给定m,对于s\in [1,m ...

  3. 洛谷 4389 付公主的背包——多项式求ln、exp

    题目:https://www.luogu.org/problemnew/show/P4389 关于泰勒展开: https://blog.csdn.net/SoHardToNamed/article/d ...

  4. luoguP4389 付公主的背包

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

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

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

  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. 【Luogu4389】付公主的背包

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

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

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

随机推荐

  1. CSS media--(来自网易)

    概述 通过媒体查询为不同的设备和大小配置不同的样式.代码展示 /* media */ /* 横屏 */ @media screen and (orientation:landscape){ } /* ...

  2. 原生JS不到30行,实现类似javascript MVC的功能-minTemplate

    严格来讲不能说是MVC,应为模版里不能写逻辑语句. 灵感来源于我的上篇文字:<封装JSON数据转自定义HTML方法parseHTML>: 这里再封装一个简单方法,在保持原来的方便改变不大的 ...

  3. Spring Mvc 一个接口多个继承; (八)

    在 spring 注解实现里,一个接口一般是不能多继承的! 除非在 bean 配置文件里有 针对这个 实现类的配置: <beans:bean id="icService" c ...

  4. git log查看某一个分支的提交

    如果想查看某一个分支的提交信息:git log 或者是查看分支名:git log $分支名/tag名/远程分支名 查看提交的详情: git log -p

  5. C++产生固定范围内的固定数量的随机数

    #include<iostream> #include<ctime> #include<random> using namespace std; void knut ...

  6. 简单解读linux的/proc下的statm、maps、memmap 内存信息文件分析【转】

    转自:https://blog.csdn.net/sctq8888/article/details/7398776 转载自:http://hi.baidu.com/deep_pro/blog/item ...

  7. linux中serial driver理解【转】

    转自:http://blog.csdn.net/laoliu_lcl/article/details/39967225 英文文档地址:myandroid/kernel_imx/Documentatio ...

  8. 使用 CasperJS 构建 Web 爬虫

    转载:https://www.oschina.net/translate/building-your-own-web-scraper-in-nodejs 从你的应用中收集数据有时候可能有点困难和艰辛. ...

  9. cas:覆盖安装

    1.首先到github上下载最新的模板代码 https://github.com/apereo/cas-overlay-template 下载完成后,导入该工程. 2.编译打包 cd cas-over ...

  10. 七、vue语法补充二(动态组件 & 异步组件、访问元素 & 组件、混入)

    1..sync 修饰符 2.3.0+ 新增 vue 修饰符sync的功能是:当一个子组件改变了一个 prop 的值时,这个变化也会同步到父组件中所绑定.类似于v-model的效果 例子: this.$ ...