题意

给定一个长为 \(n\) 的序列 \(\{a_i\}\) 对于 \(k \in [1, n]\) 求

\[f_k = \sum_{i = 1}^{n} a_i^k \pmod {998244353}
\]

\(n \le 2 \times 10^5\)

题解

不会牛顿恒等式TAT,参考了这位大佬的博客

我们令 \(F(x)\) 为 \(f_k\) 的生成函数,我们有

\[\begin{aligned}
F(x)
&= \sum_{k} (\sum_{i = 1}^{n} a_i^k) x^k\\
&=\sum_{i = 1}^n \sum_k a_i^kx^k\\
&=\sum_{i = 1}^{n} \frac{1}{1 - a_ix}\\
\end{aligned}
\]

这几步都比较基础,但看起来还是挺不可做的,我们用一些神奇的操作。

\[\begin{aligned}
F(x)
&= \sum_{i = 1}^{n} (1 + \frac{a_ix}{1 - a_ix})\\
&= n - x \sum_{i= 1}^{n} \frac{-a_i}{1 - a_ix}\\
&= n - x \sum_{i = 1}^{n} \ln'(1 - a_ix)\\
&= n - x \ln'(\prod_{i = 1}^n(1 - a_ix))
\end{aligned}
\]

我们先分治求出 \(\prod_{i = 1}^{n}(1 - a_ix)\) 然后套 \(\ln\) 的板子即可。\(\mathcal O(n \log^2 n)\)

代码

  1. #include <bits/stdc++.h>
  2. #define For(i, l, r) for (register int i = (l), i##end = int(r); i <= i##end; ++i)
  3. #define Fordown(i, r, l) for (register int i = (r), i##end = (int)(l); i >= i##end; --i)
  4. #define Rep(i, r) for (register int i = (0), i##end = int(r); i < i##end; ++i)
  5. #define Set(a, v) memset(a, v, sizeof(a))
  6. #define Cpy(a, b) memcpy(a, b, sizeof(a))
  7. #define debug(x) cout << #x << ": " << (x) << endl
  8. using namespace std;
  9. typedef vector<int> VI;
  10. template<typename T> inline bool chkmin(T &a, T b) { return b < a ? a = b, 1 : 0; }
  11. template<typename T> inline bool chkmax(T &a, T b) { return b > a ? a = b, 1 : 0; }
  12. inline int read() {
  13. int x(0), sgn(1); char ch(getchar());
  14. for (; !isdigit(ch); ch = getchar()) if (ch == '-') sgn = -1;
  15. for (; isdigit(ch); ch = getchar()) x = (x * 10) + (ch ^ 48);
  16. return x * sgn;
  17. }
  18. void File() {
  19. #ifdef zjp_shadow
  20. freopen ("2409.in", "r", stdin);
  21. freopen ("2409.out", "w", stdout);
  22. #endif
  23. }
  24. const int Mod = 998244353;
  25. inline int fpm(int x, int power) {
  26. int res(1);
  27. for (; power; power >>= 1, x = 1ll * x * x % Mod)
  28. if (power & 1) res = 1ll * res * x % Mod;
  29. return res;
  30. }
  31. int findlen(int l) {
  32. int res = 1; while (res <= l) res <<= 1; return res;
  33. }
  34. template<int Maxn>
  35. struct Poly {
  36. const int g = 3, invg = fpm(g, Mod - 2);
  37. int rev[Maxn], W[Maxn], len;
  38. void NTT(int *P, int opt) {
  39. Rep (i, len) if (i < rev[i]) swap(P[i], P[rev[i]]);
  40. for (int i = 2, p; p = i >> 1, i <= len; i <<= 1) {
  41. W[0] = 1; W[1] = fpm(~opt ? g : invg, (Mod - 1) / i);
  42. For (k, 2, p - 1) W[k] = 1ll * W[k - 1] * W[1] % Mod;
  43. for (int j = 0; j < len; j += i) Rep (k, p) {
  44. int u = P[j + k], v = 1ll * P[j + k + p] * W[k] % Mod;
  45. P[j + k] = (u + v) % Mod; P[j + k + p] = (u - v + Mod) % Mod;
  46. }
  47. }
  48. if (!~opt) {
  49. int invn = fpm(len, Mod - 2);
  50. Rep (i, len) P[i] = 1ll * P[i] * invn % Mod;
  51. }
  52. }
  53. void Prepare(int lc) {
  54. int cnt = -1;
  55. for (len = 1; len <= lc; len <<= 1) ++ cnt;
  56. Rep (i, len) rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << cnt);
  57. }
  58. int A[Maxn], B[Maxn], C[Maxn];
  59. void Mult(int *a, int *b, int *c, int la, int lb) {
  60. int lc = la + lb; Prepare(lc);
  61. if (lc <= 400) {
  62. static int tmp[410] = {0};
  63. For (i, 0, la) if (a[i]) For (j, 0, lb)
  64. tmp[i + j] = (tmp[i + j] + 1ll * a[i] * b[j]) % Mod;
  65. For (i, 0, lc) c[i] = tmp[i], tmp[i] = 0; return;
  66. }
  67. Rep (i, len) A[i] = i <= la ? a[i] : 0; NTT(A, 1);
  68. Rep (i, len) B[i] = i <= lb ? b[i] : 0; NTT(B, 1);
  69. Rep (i, len) C[i] = 1ll * A[i] * B[i] % Mod; NTT(C, -1);
  70. For (i, 0, lc) c[i] = C[i];
  71. }
  72. VI Mult(VI a, VI b) {
  73. static int ta[Maxn], tb[Maxn], tc[Maxn]; VI c;
  74. Rep (i, a.size()) ta[i] = a[i];
  75. Rep (i, b.size()) tb[i] = b[i];
  76. Mult(ta, tb, tc, a.size() - 1, b.size() - 1);
  77. Rep (i, a.size() + b.size() - 1) c.push_back(tc[i]); return c;
  78. }
  79. void Inv(int *f, int *g, int lf) {
  80. if (lf == 1) return void(g[0] = fpm(f[0], Mod - 2));
  81. Inv(f, g, lf >> 1); Prepare(lf << 1);
  82. Rep (i, len) A[i] = i < lf ? f[i] : 0; NTT(A, 1);
  83. Rep (i, len) B[i] = i < lf ? g[i] : 0; NTT(B, 1);
  84. Rep (i, len) C[i] = 1ll * A[i] * B[i] % Mod * B[i] % Mod; NTT(C, -1);
  85. Rep (i, lf) g[i] = (g[i] * 2ll + Mod - C[i]) % Mod;
  86. }
  87. int inv[Maxn];
  88. Poly() {
  89. inv[1] = 1;
  90. For (i, 2, Maxn - 1)
  91. inv[i] = 1ll * inv[Mod % i] * (Mod - Mod / i) % Mod;
  92. }
  93. void Der(int *f, int *g, int lf) {
  94. For (i, 1, lf) g[i - 1] = 1ll * i * f[i] % Mod; g[lf] = 0;
  95. }
  96. void Int(int *f, int *g, int lf) {
  97. g[0] = 0;
  98. For (i, 1, lf + 1)
  99. g[i] = 1ll * f[i - 1] * inv[i] % Mod;
  100. }
  101. void Ln(int *f, int *g, int lf) {
  102. static int der[Maxn], tmp[Maxn];
  103. Der(f, der, lf); Inv(f, tmp, lf);
  104. Mult(der, tmp, tmp, lf, lf); Int(tmp, g, lf);
  105. }
  106. };
  107. const int N = 1 << 20;
  108. Poly<N> T;
  109. int n, a[N], f[N], g[N], ans[N];
  110. VI Solve(int l, int r) {
  111. if (l == r) return {1, Mod - a[l]};
  112. int mid = (l + r) >> 1;
  113. return T.Mult(Solve(l, mid), Solve(mid + 1, r));
  114. }
  115. int main () {
  116. File();
  117. int cases = read();
  118. while (cases --) {
  119. For (i, 1, n = read()) a[i] = read() % Mod;
  120. VI res = Solve(1, n);
  121. For (i, 0, n) f[i] = res[i];
  122. T.Ln(f, g, findlen(n)); T.Der(g, f, n);
  123. ans[0] = n; For (i, 1, n) ans[i] = Mod - f[i - 1];
  124. int Ans = 0;
  125. For (i, 1, n) Ans ^= ans[i];
  126. printf ("%d\n", Ans);
  127. }
  128. return 0;
  129. }

LOJ#2409. 「THUPC 2017」小 L 的计算题 / Sum(生成函数)的更多相关文章

  1. LOJ 2409「THUPC 2017」小 L 的计算题 / Sum

    思路 和玩游戏一题类似 定义\(A_k(x)=\sum_{i=0}^\infty a_k^ix^i=\frac{1}{1-a_kx}\) 用\(\ln 'x\)代替\(\frac{1}{x}\), 所 ...

  2. 题解 「THUPC 2017」小 L 的计算题 / Sum

    题目传送门 题目大意 给出 \(a_{1,2,...,n}\),对于 \(\forall k\in [1,n]\) ,求出: \[\sum_{i=1}^{n}a_i^k \] \(n\le 2\tim ...

  3. LOJ 2288「THUWC 2017」大葱的神力

    LOJ 2288「THUWC 2017」大葱的神力 Link Solution 比较水的提交答案题了吧 第一个点爆搜 第二个点爆搜+剪枝,我的剪枝就是先算出 \(mx[i]\) 表示选取第 \(i \ ...

  4. @loj - 2977@ 「THUSCH 2017」巧克力

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 「人生就像一盒巧克力,你永远不知道吃到的下一块是什么味道.」 明 ...

  5. LOJ #2978「THUSCH 2017」杜老师

    听说LOJ传了THUSC题赶紧上去看一波 随便点了一题都不会做想了好久才会写暴力爆了一发过了... LOJ #2978 题意 $ T$次询问,每次询问$ L,R$,问有多少种选取区间中数的方案使得选出 ...

  6. LOJ 2980 「THUSCH 2017」大魔法师——线段树

    题目:https://loj.ac/problem/2980 线段树维护矩阵. 然后是 30 分.似乎是被卡常了?…… #include<cstdio> #include<cstri ...

  7. LOJ 2979 「THUSCH 2017」换桌——多路增广费用流

    题目:https://loj.ac/problem/2979 原来的思路: 优化连边.一看就是同一个桌子相邻座位之间连边.相邻桌子对应座位之间连边. 每个座位向它所属的桌子连边.然后每个人建一个点,向 ...

  8. LOJ 2978 「THUSCH 2017」杜老师——bitset+线性基+结论

    题目:https://loj.ac/problem/2978 题解:https://www.cnblogs.com/Paul-Guderian/p/10248782.html 第 i 个数的 bits ...

  9. LOJ 2997 「THUSCH 2017」巧克力——思路+随机化+斯坦纳树

    题目:https://loj.ac/problem/2977 想到斯坦纳树.但以为只能做 “包含一些点” 而不是 “包含一些颜色” .而且不太会处理中位数. 其实 “包含一些颜色” 用斯坦纳树做也和普 ...

随机推荐

  1. Sublime Text 3关闭自动升级提醒

    由于种种原因,导致不想升级现有版本的ST3,但是被它的升级提醒弹窗严重骚扰! ||||||||||| 解 决 办 法 ||||||||||| 1.首选项 - 设置 - 用户(快捷键 ❀,)打开“Pre ...

  2. 洛谷P1084 疫情控制

    题目 细节比较多的二分+跟LCA倍增差不多的思想 首先有这样一个贪心思路,深度越低的检查点越好,而最长时间和深度具有单调性,即给定时间越长,每个军队能向更浅的地方放置检查点.因此可以考虑二分时间,然后 ...

  3. nginx架构分析之 架构

    Nginx服务器使用 master/worker 多进程模式. 主进程(Master process)启动后,会接收和处理外部信号: 主进程启动后通过fork() 函数产生一个或多个子进程(work ...

  4. 「BJOI2018」治疗之雨

    传送门 Description 有\(m+1\)个数,第一个数为\(p\),每轮:选一个数\(+1\),再依次选\(k\)个数\(-1\) 要求如果第一个数\(=N\),不能选它\(+1\),如果第一 ...

  5. ~/.ssh/config文件的使用

    Host github-A HostName github.com User git IdentityFile /Users/xxx/.ssh/id_rsa_A IdentitiesOnly yes ...

  6. 歪国人整理的 2019 年 Java 开发路线图,值得参考!

      许多Java开发人员都希望通过某种Java成长路线图,来解答有关:该学习哪些技术,使用哪些工具以及框架之类的问题. 在此,我将向大家展示一张根据自己多年经验总结出的路线图.该路线图在保持简单可行的 ...

  7. 堆叠注入——BUUCTF-随便注

    由题目提示知道,这题需要进行sql注入 输入1'发现报错 再输入1';show batabases#出现了一大堆数据库 再输入1';show tables#出现了两个表 猜测flag在这2个表中,输入 ...

  8. Java API设计原则清单

    在设计Java API的时候总是有很多不同的规范和考量.与任何复杂的事物一样,这项工作往往就是在考验我们思考的缜密程度.就像飞行员起飞前的检查清单,这张清单将帮助软件设计者在设计Java API的过程 ...

  9. ip rule实现源IP路由,实现一个主机多IP(或多网段)同时通(外部看是完全两个独立IP)

    利用ip rule实现基于源地址区分路由表,实现一个主机多IP网段同时通.(外部的一个主机无论访问哪个网段都可以访问通)实际应用:创建路由表table200ip route add 192.168.1 ...

  10. mac下使用java测试iOS推送

    首先mac下有很多现在的测试iOS推送软件,为什么要用java程序测试呢: 因为大多数后台推送服务可能是JAVA开发的,那么为了验证我们在MAC上导出的推送证书文件是否正确: 制作开发证书的iOS开发 ...