2019徐州网络赛 H.function
题意:
先有\(n=p_1^{k_1}p_2^{k_2}\cdots p_m^{k_m}\),定义\(f(n)=k_1+k_2+\cdots+k_m\)。
现在计算
\]
思路:
首先注意到\(f\)函数有这样一个性质:\(f(ab)=f(a)+f(b)\)。
那么我们化简所求式子有:
&\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\)了,那么结果就和上面的差不多。
总结一下,最后推得的式子就为:
\]
发现当\(k>1\)的时候很好处理,直接暴力算就行,照着上面式子写就行。
当\(k=1\)的时候,因为是求每个素数的和,所以可以直接用\(min25\)筛的方法来搞。
细节详见代码吧,感觉也没啥细节,会\(min25\)就行。(然而我把线性筛写错没发现,调了一上午...)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e6 + 5, MOD = 998244353, inv = 499122177;
ll n, z;
bool chk[N];
int prime[N], tot;
ll p[N];
void pre() {
for(int i = 2; i <= z; i++) {
if(!chk[i]) {
prime[++tot] = i;
p[tot] = (p[tot - 1] + i) % MOD;
}
for(int j = 1; j <= tot && 1ll * i * prime[j] <= z; j++) {
chk[i * prime[j]] = 1;
if(i % prime[j] == 0) break;
}
}
}
ll w[N], g1[N], g2[N];
int ind[N], ind2[N];
int cnt;
void calc_g() {
for(ll i = 1, j; i <= n; i = j + 1) {
j = n / (n / i);
w[++cnt] = n / i;
if(w[cnt] <= z) ind[w[cnt]] = cnt;
else ind2[n / w[cnt]] = cnt;
g1[cnt] = (w[cnt] - 1) % MOD;
g2[cnt] = w[cnt] % MOD * ((w[cnt] + 1) % MOD) % MOD * inv % MOD - 1;
}
for(int i = 1; i <= tot; i++) {
for(int j = 1; j <= cnt && 1ll * prime[i] * prime[i] <= w[j]; j++) {
ll tmp = w[j] / prime[i], k;
if(tmp <= z) k = ind[tmp]; else k = ind2[n / tmp];
g1[j] -= (g1[k] - i + 1) % MOD;
g2[j] -= 1ll * (p[i] - p[i - 1]) * (g2[k] - p[i - 1]) % MOD;
g1[j] %= MOD; g2[j] %= MOD;
if(g1[j] < 0) g1[j] += MOD;
if(g2[j] < 0) g2[j] += MOD;
}
}
}
ll work() {
ll ans = 0;
for(ll i = 1, j; i <= n; i = j + 1) {
j = n / (n / i);
ll l = ((i - 1 <= z) ? ind[i - 1] : ind2[(n / (i - 1))]);
ll r = ((j <= z) ? ind[j] : ind2[n / j]);
ans += (n / i) % MOD * ((n + 1) % MOD) % MOD * (g1[r] - g1[l]) % MOD;
ans -= (n / i) % MOD * ((n / i + 1) % MOD) % MOD * inv % MOD * (g2[r] - g2[l]) % MOD;
ans = (ans % MOD + MOD) % MOD;
}
for(int i = 1; i <= tot; i++) {
ll prim = prime[i];
for(; prim * prime[i] <= n;) {
prim *= prime[i];
ans += (n + 1) % MOD * ((n / prim) % MOD) % MOD;
ans %= MOD;
ans -= (n / prim) % MOD * (n / prim + 1) % MOD * inv % MOD * prim % MOD;
ans %= MOD;
}
}
if(ans < 0) ans += MOD;
return ans;
}
int main() {
ios::sync_with_stdio(false); cin.tie(0);
cin >> n; z = sqrt(n) + 1;
pre();
calc_g();
cout << work();
return 0;
}
2019徐州网络赛 H.function的更多相关文章
- 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)); 我们分两 ...
- ICPC 2019 徐州网络赛
ICPC 2019 徐州网络赛 比赛时间:2019.9.7 比赛链接:The Preliminary Contest for ICPC Asia Xuzhou 2019 赛后的经验总结 // 比赛完才 ...
- 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], ...
- 2019徐州网络赛 I J M
I. query 比赛时候没有预处理因子疯狂t,其实预处理出来因子是\(O(nlog(n))\)级别的 每个数和他的因子是一对偏序关系,因此询问转化为(l,r)区间每个数的因子在区间(l,r)的个数 ...
- 2019南昌网络赛H The Nth Item(打表找询问循环节 or 分段打表)
https://nanti.jisuanke.com/t/41355 思路 从fib循环节入手,\(O(1e7log(1e9))\),tle 因为只需要输出所有询问亦或后的结果,所以考虑答案的循环节, ...
- 【树状数组】2019徐州网络赛 query
(2)首先成倍数对的数量是nlogn级别的,考虑每一对[xL,xR](下标的位置,xL < xR)会对那些询问做出贡献,如果qL <= xL && qR >= xR, ...
- query 2019徐州网络赛(树状数组)
query \[ Time Limit: 2000 ms \quad Memory Limit: 262144 kB \] 题意 补题才发现比赛的时候读了一个假题意.... 给出长度为 \(n\) 的 ...
- [2019徐州网络赛J题]Random Access Iterator
题目链接 大致题意:从根节点出发,在节点x有son[x]次等概率进入儿子节点,求到达最深深度的概率.son[x]为x节点的儿子节点个数. 又又又又没做出来,心态崩了. 下来看了官方题解后发觉自己大体思 ...
- 2019徐州网络赛 I.query
这题挺有意思哈!!!看别人写的博客,感觉瞬间就懂了. 这道题大概题意就是,给一串序列,我们要查找到l-r区间内,满足min(a[ i ],a[ j ]) = gcd(a[ i ],a[ j ]) 其实 ...
随机推荐
- bay——RAC 关闭和启动顺序,状态查看.txt
oracle 11g rac 关闭和启动顺序,状态查看https://www.cnblogs.com/hellojesson/p/4501112.html----------------------- ...
- 初级模拟电路:3-8 BJT数据规格书(直流部分)
回到目录 本小节我们以2N4123通用型BJT硅基晶体管为例,来介绍如何阅读BJT的数据规格书,点此链接可以阅读和下载2N4123的数据规格书. 1. 总体性能 打开datasheet后,首先看标题: ...
- fstab是什么?被谁用?怎么写?
关键词:fstab.mount -a.fsck等等. 1. fstab是干什么的? fstab是file system table的意思,即文件系统表. 它在开机的时候告诉系统挂载哪些分区.挂载点是什 ...
- 新终端必须source /etc/profile的解决办法,同时解决变色问题
Linux环境变量文件 /etc/profile:在登录时,操作系 统定制用户环境时使用的第一个文件 ,此文件为系统的每个用户设置环境信息,当用户第一次登录时,该文件被执行. /etc /enviro ...
- linux常用命令指南——查找文件我最强:find
2.3.2 查找文件我最强:find 2.3.2.1 find查找常用命令示例 find / -name 'wfy.txt' # 从根目录下开始查找文件wfy.txt find . -name '*f ...
- 使用Runtime的hook技术为tableView实现一个空白缺省页
一.介绍 UITableView和UICollectionView是iOS开发最常用的控件,也是必不可少的控件,这两个控件基本能实现各种各样的界面样式. 它们都是通过代理模式监测数据源的有无对数据进行 ...
- Tree-Shaking性能优化实践 - 原理篇
Tree-Shaking性能优化实践 - 原理篇 一. 什么是Tree-shaking 先来看一下Tree-shaking原始的本意 上图形象的解释了Tree-shaking 的本意,本文所说的前 ...
- python做中学(九)定时器函数的用法
程序中,经常用到这种,就是需要固定时间执行的,或者需要每隔一段时间执行的.这里经常用的就是Timer定时器.Thread 类有一个 Timer子类,该子类可用于控制指定函数在特定时间内执行一次. 可以 ...
- SVN基本使用
1.把服务器的所有内容下载到本地 svn checkout 服务器地址 --username=使用者 --password=密码 2.添加文件 touch main.m(文件名) : 创建main.m ...
- java线程join方法使用方法简介
本博客简介介绍一下java线程的join方法,join方法是实现线程同步,可以将原本并行执行的多线程方法变成串行执行的 如图所示代码,是并行执行的 public class ThreadTest { ...