题意:

先有\(n=p_1^{k_1}p_2^{k_2}\cdots p_m^{k_m}\),定义\(f(n)=k_1+k_2+\cdots+k_m\)。

现在计算

\[\sum_{i=1}^nf(i!)\% 998244353
\]

思路:

首先注意到\(f\)函数有这样一个性质:\(f(ab)=f(a)+f(b)\)。

那么我们化简所求式子有:

\[\begin{aligned}
&\sum_{i=1}^nf(i!)\\
=&\sum_{i=1}^n\sum_{j=1}^if(j)\\
=&\sum_{i=1}^n (n-i+1)f(i)\\
=&(n+1)\sum_{i=1}^nf(i)-\sum_{i=1}^n if(i)\\
\end{aligned}
\]

注意\(f\)并不是积性函数,但是我们根据上面的性质,发现\(\sum_{i=1}^nf(i)\)其实求的就是\(1,2,\cdots,n\)中,每个数的质因子指数和。就和对\(n!\)做质因子分解一样,我们只需要依次考虑每个素数的贡献,那么就可以化为:\((n+1)\sum_{i=1}^n[i\in P]\sum_{k=1}^{34}\lfloor\frac{n}{i^k}\rfloor\)

那后半部分呢?

还是像上面一样,每个质数依次考虑。假设对于质数\(p\)而言,那么所有有贡献的就是\(p,2\cdot p,\cdots,\lfloor\frac{n}{p}\rfloor \cdot p\),每个\(f\)的贡献为\(1\),那么答案就是\((1+2+\cdots+\lfloor\frac{n}{p}\rfloor)p\);对于\(p^2\)而言,每个\(f\)的贡献为\(2\),但是之前在\(p\)的时候已经算上一次,所以贡献就为\(1\)了,那么结果就和上面的差不多。

总结一下,最后推得的式子就为:

\[(n+1)\sum_{i=1}^n[i\in P]\sum_{k=1}^{34}\lfloor\frac{n}{i^k}\rfloor-\sum_{i=1}^n[i\in P]\sum_{k=1}^{34}\frac{\lfloor\frac{n}{i^k}\rfloor(\lfloor\frac{n}{i^k}\rfloor+1)}{2}i^k
\]

发现当\(k>1\)的时候很好处理,直接暴力算就行,照着上面式子写就行。

当\(k=1\)的时候,因为是求每个素数的和,所以可以直接用\(min25\)筛的方法来搞。

细节详见代码吧,感觉也没啥细节,会\(min25\)就行。(然而我把线性筛写错没发现,调了一上午...)

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. typedef long long ll;
  4. const int N = 1e6 + 5, MOD = 998244353, inv = 499122177;
  5. ll n, z;
  6. bool chk[N];
  7. int prime[N], tot;
  8. ll p[N];
  9. void pre() {
  10. for(int i = 2; i <= z; i++) {
  11. if(!chk[i]) {
  12. prime[++tot] = i;
  13. p[tot] = (p[tot - 1] + i) % MOD;
  14. }
  15. for(int j = 1; j <= tot && 1ll * i * prime[j] <= z; j++) {
  16. chk[i * prime[j]] = 1;
  17. if(i % prime[j] == 0) break;
  18. }
  19. }
  20. }
  21. ll w[N], g1[N], g2[N];
  22. int ind[N], ind2[N];
  23. int cnt;
  24. void calc_g() {
  25. for(ll i = 1, j; i <= n; i = j + 1) {
  26. j = n / (n / i);
  27. w[++cnt] = n / i;
  28. if(w[cnt] <= z) ind[w[cnt]] = cnt;
  29. else ind2[n / w[cnt]] = cnt;
  30. g1[cnt] = (w[cnt] - 1) % MOD;
  31. g2[cnt] = w[cnt] % MOD * ((w[cnt] + 1) % MOD) % MOD * inv % MOD - 1;
  32. }
  33. for(int i = 1; i <= tot; i++) {
  34. for(int j = 1; j <= cnt && 1ll * prime[i] * prime[i] <= w[j]; j++) {
  35. ll tmp = w[j] / prime[i], k;
  36. if(tmp <= z) k = ind[tmp]; else k = ind2[n / tmp];
  37. g1[j] -= (g1[k] - i + 1) % MOD;
  38. g2[j] -= 1ll * (p[i] - p[i - 1]) * (g2[k] - p[i - 1]) % MOD;
  39. g1[j] %= MOD; g2[j] %= MOD;
  40. if(g1[j] < 0) g1[j] += MOD;
  41. if(g2[j] < 0) g2[j] += MOD;
  42. }
  43. }
  44. }
  45. ll work() {
  46. ll ans = 0;
  47. for(ll i = 1, j; i <= n; i = j + 1) {
  48. j = n / (n / i);
  49. ll l = ((i - 1 <= z) ? ind[i - 1] : ind2[(n / (i - 1))]);
  50. ll r = ((j <= z) ? ind[j] : ind2[n / j]);
  51. ans += (n / i) % MOD * ((n + 1) % MOD) % MOD * (g1[r] - g1[l]) % MOD;
  52. ans -= (n / i) % MOD * ((n / i + 1) % MOD) % MOD * inv % MOD * (g2[r] - g2[l]) % MOD;
  53. ans = (ans % MOD + MOD) % MOD;
  54. }
  55. for(int i = 1; i <= tot; i++) {
  56. ll prim = prime[i];
  57. for(; prim * prime[i] <= n;) {
  58. prim *= prime[i];
  59. ans += (n + 1) % MOD * ((n / prim) % MOD) % MOD;
  60. ans %= MOD;
  61. ans -= (n / prim) % MOD * (n / prim + 1) % MOD * inv % MOD * prim % MOD;
  62. ans %= MOD;
  63. }
  64. }
  65. if(ans < 0) ans += MOD;
  66. return ans;
  67. }
  68. int main() {
  69. ios::sync_with_stdio(false); cin.tie(0);
  70. cin >> n; z = sqrt(n) + 1;
  71. pre();
  72. calc_g();
  73. cout << work();
  74. return 0;
  75. }

2019徐州网络赛 H.function的更多相关文章

  1. 2019徐州网络赛H :function (min25筛)

    题意:f(i)=i的幂次之和. 求(N+1-i)*f(i)之和. 思路:可以推论得对于一个素数p^k,其贡献是ans=(N+1)[N/(P^k)]+P^k(1+2+3...N/(P^k)); 我们分两 ...

  2. ICPC 2019 徐州网络赛

    ICPC 2019 徐州网络赛 比赛时间:2019.9.7 比赛链接:The Preliminary Contest for ICPC Asia Xuzhou 2019 赛后的经验总结 // 比赛完才 ...

  3. 2018徐州网络赛H. Ryuji doesn't want to study

    题目链接: https://nanti.jisuanke.com/t/31458 题解: 建立两个树状数组,第一个是,a[1]*n+a[2]*(n-1)....+a[n]*1;第二个是正常的a[1], ...

  4. 2019徐州网络赛 I J M

    I. query 比赛时候没有预处理因子疯狂t,其实预处理出来因子是\(O(nlog(n))\)级别的 每个数和他的因子是一对偏序关系,因此询问转化为(l,r)区间每个数的因子在区间(l,r)的个数 ...

  5. 2019南昌网络赛H The Nth Item(打表找询问循环节 or 分段打表)

    https://nanti.jisuanke.com/t/41355 思路 从fib循环节入手,\(O(1e7log(1e9))\),tle 因为只需要输出所有询问亦或后的结果,所以考虑答案的循环节, ...

  6. 【树状数组】2019徐州网络赛 query

    (2)首先成倍数对的数量是nlogn级别的,考虑每一对[xL,xR](下标的位置,xL < xR)会对那些询问做出贡献,如果qL <= xL && qR >= xR, ...

  7. query 2019徐州网络赛(树状数组)

    query \[ Time Limit: 2000 ms \quad Memory Limit: 262144 kB \] 题意 补题才发现比赛的时候读了一个假题意.... 给出长度为 \(n\) 的 ...

  8. [2019徐州网络赛J题]Random Access Iterator

    题目链接 大致题意:从根节点出发,在节点x有son[x]次等概率进入儿子节点,求到达最深深度的概率.son[x]为x节点的儿子节点个数. 又又又又没做出来,心态崩了. 下来看了官方题解后发觉自己大体思 ...

  9. 2019徐州网络赛 I.query

    这题挺有意思哈!!!看别人写的博客,感觉瞬间就懂了. 这道题大概题意就是,给一串序列,我们要查找到l-r区间内,满足min(a[ i ],a[ j ]) = gcd(a[ i ],a[ j ]) 其实 ...

随机推荐

  1. bay——RAC 关闭和启动顺序,状态查看.txt

    oracle 11g rac 关闭和启动顺序,状态查看https://www.cnblogs.com/hellojesson/p/4501112.html----------------------- ...

  2. 初级模拟电路:3-8 BJT数据规格书(直流部分)

    回到目录 本小节我们以2N4123通用型BJT硅基晶体管为例,来介绍如何阅读BJT的数据规格书,点此链接可以阅读和下载2N4123的数据规格书. 1. 总体性能 打开datasheet后,首先看标题: ...

  3. fstab是什么?被谁用?怎么写?

    关键词:fstab.mount -a.fsck等等. 1. fstab是干什么的? fstab是file system table的意思,即文件系统表. 它在开机的时候告诉系统挂载哪些分区.挂载点是什 ...

  4. 新终端必须source /etc/profile的解决办法,同时解决变色问题

    Linux环境变量文件 /etc/profile:在登录时,操作系 统定制用户环境时使用的第一个文件 ,此文件为系统的每个用户设置环境信息,当用户第一次登录时,该文件被执行. /etc /enviro ...

  5. linux常用命令指南——查找文件我最强:find

    2.3.2 查找文件我最强:find 2.3.2.1 find查找常用命令示例 find / -name 'wfy.txt' # 从根目录下开始查找文件wfy.txt find . -name '*f ...

  6. 使用Runtime的hook技术为tableView实现一个空白缺省页

    一.介绍 UITableView和UICollectionView是iOS开发最常用的控件,也是必不可少的控件,这两个控件基本能实现各种各样的界面样式. 它们都是通过代理模式监测数据源的有无对数据进行 ...

  7. Tree-Shaking性能优化实践 - 原理篇

    Tree-Shaking性能优化实践 - 原理篇   一. 什么是Tree-shaking 先来看一下Tree-shaking原始的本意 上图形象的解释了Tree-shaking 的本意,本文所说的前 ...

  8. python做中学(九)定时器函数的用法

    程序中,经常用到这种,就是需要固定时间执行的,或者需要每隔一段时间执行的.这里经常用的就是Timer定时器.Thread 类有一个 Timer子类,该子类可用于控制指定函数在特定时间内执行一次. 可以 ...

  9. SVN基本使用

    1.把服务器的所有内容下载到本地 svn checkout 服务器地址 --username=使用者 --password=密码 2.添加文件 touch main.m(文件名) : 创建main.m ...

  10. java线程join方法使用方法简介

    本博客简介介绍一下java线程的join方法,join方法是实现线程同步,可以将原本并行执行的多线程方法变成串行执行的 如图所示代码,是并行执行的 public class ThreadTest { ...