题解[LuoguP6222]「P6156简单题」加强版

加强版很好地体现了这个题的真正价值。(当然是指卡常

本题解给出了本题更详尽的推倒导和思考过程,思路与 CYJian 的类似,具体式子的个别地方换用了更易于理解的式子,可以看作是给数论新手的对莫反套路和欧拉筛套路的补充解释和技巧指导。

Problem

最多 \(10^4\) 组询问,每次询问给定 \(n\) ,求

\[\begin{aligned}
\sum_{i=1}^n\sum_{j=1}^n(i+j)^K\gcd(i,j)\mu^2(\gcd(i,j))
\end{aligned}
\]

对 \(2^{32}\) 取模。其中各个询问的 \(K\) 相等。\(n\le10^7\)

Solution

对 \(2^{32}\) 取模直接 unsigned int 自然溢出即可。

整体

考虑颓推式子:可以看到多次出现了 \(\gcd\) ,尝试莫反套路,先枚举 \(\gcd(i,j)=d\) ,然后将 \(d\) 提出到外层,最后对内层 \([gcd(i,j)=1]\) 莫反 。

\[\begin{aligned}
ans&=\sum_{i=1}^n\sum_{j=1}^n(i+j)^K\gcd(i,j)\mu^2(\gcd(i,j))\\
&=\sum_{i=1}^n\sum_{j=1}^n(i+j)^K\sum_{d\mid i,d\mid j}d\mu^2(d)[\gcd(i,j)=d]\\
&=\sum_{d=1}^nd\mu^2(d)\sum_{i=1}^{\lfloor\frac nd\rfloor}\sum_{j=1}^{\lfloor\frac nd\rfloor}(id+jd)^K[\gcd(id,jd)=d]\\
&=\sum_{d=1}^nd^{K+1}\mu^2(d)\sum_{i=1}^{\lfloor\frac nd\rfloor}\sum_{j=1}^{\lfloor\frac nd\rfloor}(i+j)^K[\gcd(i,j)=1]\\
&=\sum_{d=1}^nd^{K+1}\mu^2(d)\sum_{i=1}^{\lfloor\frac nd\rfloor}\sum_{j=1}^{\lfloor\frac nd\rfloor}(i+j)^K\sum_{t|i,t|j}\mu(t)
\end{aligned}
\]

按照我们的经验,可以想到将 \(t\) 也提出到外层并枚举 \(T=td\) 从而使得式子变成 \(n\) 个只关于 \(T\) 的函数的和(这种思想是很多数论题降低复杂度的关键,后面还会用)。

\[\begin{aligned}
ans&=\sum_{d=1}^nd^{K+1}\mu^2(d)\sum_{i=1}^{\lfloor\frac nd\rfloor}\sum_{j=1}^{\lfloor\frac nd\rfloor}(i+j)^K\sum_{t|i,t|j}\mu(t)\\
&=\sum_{d=1}^nd^{K+1}\mu^2(d)\sum_t^{\lfloor\frac nd\rfloor}\mu(t)\sum_{i=1}^{\lfloor\frac n{dt}\rfloor}\sum_{j=1}^{\lfloor\frac n{dt}\rfloor}(it+jt)^K\\
&=\sum_{d=1}^nd\mu^2(d)\sum_t^{\lfloor\frac nd\rfloor}(dt)^K\mu(t)\sum_{i=1}^{\lfloor\frac n{dt}\rfloor}\sum_{j=1}^{\lfloor\frac n{dt}\rfloor}(i+j)^K\\
&=\sum_{T=1}^nT^K\sum_{d|T} d\mu^2(d)\mu(\frac Td)\sum_{i=1}^{\lfloor\frac n{T}\rfloor}\sum_{j=1}^{\lfloor\frac n{T}\rfloor}(i+j)^K
\end{aligned}
\]

分离

\(f(x)\)

这时候感觉已经很难再整体推了,那么我们来观察一下式子。

令 \(f(T)=\sum_{d|T}d\mu^2(d)\mu(\frac Td)\) ,可以看出这是一堆积性函数做乘法和狄利克雷卷积,得到的结果依然是积性函数,可以考虑用欧拉筛预处理出来。

按照一般欧拉筛预处理积性函数的套路,先考虑在素数次幂上取值,再用积性函数的性质找到最小质因子转移。

那我们来讨论一下这个函数的取值(\(p\) 表示质数):

  1. \(f(p^0)\):即 \(f(1)=1\) ,这个直接赋值就好,因为欧拉筛不考虑 \(1\)。

  2. \(f(p)\):\(p\) 只有两个因子:\(p\) 和 \(1\) ,其中 \(\mu(p)=-1\),\(\mu(1)=1\)。\(f(p)=\mu^2(p)\mu(1)p+\mu^2(1)\mu(p)=p-1\) 。

  3. \(f(p^2)\):\(p^2\) 有三个因子:\(p^2\) , \(p\) 和 \(1\) ,其中 \(\mu(p^2)=0\),\(\mu(p)=-1\),\(\mu(1)=1\),所以带 \(\mu(p^2)\) 的项都不会造成贡献。\(f(p^2)=\mu^3(p)p=-p\)

  4. \(f(p^k)(k>2)\):考虑某一项 \(\mu^2(p^l)\mu(p^{k-l})p^l\):当 \(l\geq 2\) 时,\(\mu^2(p^l)=0\),该项无贡献;当 \(l<2\) 时,\(k-l\geq 2\),\(\mu(p^{k-l})=0\) 该项无贡献。\(f(p^k)=0(k>2)\)

所以我们可以在筛的时候判一下最小质因子的指数转移,并乘上 \(T^k\)(这个也可以筛出来),具体实现见代码。

\(g(x)\)

那我们看看剩下的这一部分:令 \(g(n)=\sum_{i=1}^n\sum_{j=1}^n(i+j)^K\)。这里我们又可以考虑枚举 \(s=i+j\) 来使得内层是只有一个参数的函数。

\[\begin{aligned}
g(n)&=\sum_{i=1}^n\sum_{j=1}^n(i+j)^K\\
&=\sum_{s=2}^{2n}\sum_{i=\max(s-n,1)}^{\min(n,s-1)}s^K\\
&=\sum_{s=2}^{2n}(\min(n,s-1)-\max(s-n,1)+1)s^K
\end{aligned}
\]

我们发现出现了非常难处理的 \(\max\) 和 \(\min\) 。考虑通过钦定判断的结果来消去这种难处理的基于判断的函数。

\[\begin{aligned}
g(n)&=\sum_{s=2}^{2n}(\min(n,s-1)-\max(s-n,1)+1)s^K\\
&=\sum_{s=n+1}^{2n}(n-(s-n)+1)s^K+\sum_{s=2}^n((s-1)-1+1)s^K\\
&=\sum_{s=n+1}^{2n}(2n-s+1)s^K+\sum_{s=2}^n(s-1)s^K
\end{aligned}
\]

仔细观察,我们发现系数中同时包含了常数 \(n\) 和 \(1\),以及变量 \(s\) 。考虑把所有的常数系数都提出来。

\[\begin{aligned}
g(n)&=\sum_{s=n+1}^{2n}(2n-s+1)s^K+\sum_{s=2}^n(s-1)s^K\\
&=(2n+1)\sum_{s=n+1}^{2n}s^K-\sum_{s=n+1}^{2n}s^{K+1}+\sum_{s=2}^ns^{K+1}-\sum_{s=2}^ns^K
\end{aligned}
\]

此时已经将 \(g(n)\) 转化为几个 \(s^K\) 和 \(s^{K+1}\) 的前缀和了,这个可以用欧拉筛筛出来再做前缀和。

合并

目前我们已经得到 \(f(x)\) 和 \(g(x)\) 的 \(O(1)\) 查询方法,所以可以将整个函数作为一个整体来代入回原式寻找下一步的方向(这里看作 \(T^K\) 已经并入到 \(f(x)\) 中了)。

\[\begin{aligned}
ans&=\sum_{T=1}^nf(T)g(\lfloor\frac nT\rfloor)
\end{aligned}
\]

\(\sum\) 里套 \(\lfloor\frac nT\rfloor\) ,想到了什么?数论分块!不同的 \(g(\lfloor\frac nT\rfloor)\) 只会有 \(\sqrt n\) 种不同的取值,我们可以考虑预处理出 \(f(T)\) 的前缀和进行计算,具体实现见代码。

Core Code

附有详细注释,可放心食用!

typedef unsigned int UI;//自然溢出

const UI N=20000000,K=(1<<31);//这里 N 开双倍是因为 g(x) 中有 2n 的项。

UI n,d,nn;
UI p[N+10],tp,pk[N+10],pk1[N+10],f[N/2+10];//这里开一半是因为这题卡空间。
bool b[N+10]; inline void MakePrime(){
pk[1]=f[1]=1;
for(UI i=2;i<=nn;++i){
if(!b[i]){
p[++tp]=i,pk[i]=Pow(i,d);
if(i<=nn/2)
f[i]=i-1;//f 不需要开到 2n
}
for(UI j=1;j<=tp&&p[j]*i<=nn;++j){
UI t=p[j]*i;
b[t]=1;
pk[t]=pk[p[j]]*pk[i];//i^k 是完全积性函数
if(i%p[j])
f[t]=f[i]*f[p[j]];//如果互质就直接积性函数相乘
else{
UI tt=i/p[j];
if(tt%p[j])
f[t]=-p[j]*f[tt];//如果 i 中只有 1 个 p[j] 那么 p[j]*p[j] 和 i/p[j] 互质。
else
f[t]=0;//k>2 的情况
break;
}
}
}
for(UI i=1;i<=nn/2;++i)
f[i]=f[i-1]+f[i]*pk[i];//将 T^K 并入 f 中
for(UI i=1;i<=nn;++i)
pk1[i]=pk1[i-1]+pk[i]*i,pk[i]+=pk[i-1];//pk[i] 为 i^k 的前缀和,pk1[i] 为 i^(k+1) 的前缀和。
} inline UI A(UI x){
return (2*x+1)*(pk[x<<1]-pk[x])+pk1[x]-(pk1[x<<1]-pk1[x])-pk[x];//g(x)
} inline void Solve(){
UI ans=0;
n=read();
for(UI l=1,r;l<=n;l=r+1){
r=n/(n/l);
ans+=A(n/l)*(f[r]-f[l-1]);//数论分块
}
printf("%u\n",ans);
} int main(){
UI T=read();
nn=read()*2,d=read();//nn 表示最大的 n ,而筛法要求筛到 2n,所以将 nn*=2
MakePrime();
while(T--)
Solve();
return 0;
}

感谢观赏。

题解[LuoguP6222]「P6156简单题」加强版的更多相关文章

  1. 洛谷 P6222 - 「P6156 简单题」加强版(莫比乌斯反演)

    原版传送门 & 加强版传送门 题意: \(T\) 组数据,求 \(\sum\limits_{i=1}^n\sum\limits_{j=1}^n(i+j)^k\mu^2(\gcd(i,j))\g ...

  2. P6222 「简单题」加强版 莫比乌斯反演 线性筛积性函数

    LINK:简单题 以前写过弱化版的 不过那个实现过于垃圾 少预处理了一个东西. 这里写一个实现比较精细了. 最后可推出式子:\(\sum_{T=1}^nsum(\frac{n}{T})\sum_{x| ...

  3. P6222-「P6156 简单题」加强版【莫比乌斯反演】

    正题 题目链接:https://www.luogu.com.cn/problem/P6222 题目大意 给出\(k\),\(T\)组询问给出\(n\)求 \[\sum_{i=1}^n\sum_{j=1 ...

  4. 「bzoj3687: 简单题」

    题目 发现需要一个\(O(n\sum a_i )\)的做法 于是可以直接做一个背包,\(dp[i]\)表示和为\(i\)的子集是否有奇数种 \(bitset\)优化一下就好了 #include< ...

  5. [LOJ#6002]「网络流 24 题」最小路径覆盖

    [LOJ#6002]「网络流 24 题」最小路径覆盖 试题描述 给定有向图 G=(V,E).设 P 是 G 的一个简单路(顶点不相交)的集合.如果 V 中每个顶点恰好在 P 的一条路上,则称 P 是  ...

  6. LOJ6000 - 「网络流 24 题」搭配飞行员

    原题链接 题意简述 求二分图的最大匹配. 题解 这里写的是匈牙利算法. 表示节点的当前匹配. 为真表示在这一轮匹配中,无法给节点一个新的匹配.所以如果为真就不用再dfs它了,直接continue就好. ...

  7. LibreOJ 6003. 「网络流 24 题」魔术球 贪心或者最小路径覆盖

    6003. 「网络流 24 题」魔术球 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:Special Judge 上传者: 匿名 提交提交记录统计讨论测试数据 ...

  8. LibreOJ #6002. 「网络流 24 题」最小路径覆盖

    #6002. 「网络流 24 题」最小路径覆盖 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:Special Judge 上传者: 匿名 提交提交记录统计讨论测 ...

  9. 【刷题】LOJ 6227 「网络流 24 题」最长k可重线段集问题

    题目描述 给定平面 \(\text{xoy}\) 上 \(n\) 个开线段组成的集合 \(\text{I}\) ,和一个正整数 \(k\) ,试设计一个算法. 从开线段集合 \(\text{I}\) ...

  10. Libre 6007 「网络流 24 题」方格取数 / Luogu 2774 方格取数问题 (网络流,最大流)

    Libre 6007 「网络流 24 题」方格取数 / Luogu 2774 方格取数问题 (网络流,最大流) Description 在一个有 m*n 个方格的棋盘中,每个方格中有一个正整数.现要从 ...

随机推荐

  1. 集合框架-Collection集合

    集合框架 JAVASE提供了满足各种需求的APl,在使用这些API前,先了解其继承与接口操作架构,才能了解何时采用哪个类,以及类之间如何彼此合作,从而达到灵活应用.集合按照其存储结构可以分为两大类,分 ...

  2. Unity - 自定义Log

    嗨,崽崽们大家好.实在是不知道写个啥了,最近总是恍惚,今儿偷个懒吧,给大家推荐一个小黑自己写的小型日志工具,在一些小项目中管够使用了. 那有人会问了,Unity不是自带日志么,为什么还要自己做个小工具 ...

  3. centos7笔记本使用iptables服务,将笔记本模拟成为出口路由器 PPPOE拨号+NAT+端口映射

    郑州洪水,闲置在家,捣鼓捣鼓 centos7笔记本使用iptables服务,将笔记本模拟成为出口路由器 PPPOE拨号+NAT+端口映射 环境: 1.笔记本单网口,无法做路由网关,手里有个闲置的USB ...

  4. OpenMP For Construct dynamic 调度方式实现原理和源码分析

    OpenMP For Construct dynamic 调度方式实现原理和源码分析 前言 在本篇文章当中主要给大家介绍 OpenMp for construct 的实现原理,以及与他相关的动态库函数 ...

  5. JavaScript 评测代码运行速度

    一.使用 performance.now() API 在 JavaScript 中,可以使用 performance.now() API 来评测代码的运行速度.该 API 返回当前页面的高精度时间戳, ...

  6. Nginx09 http的keepalive及在nginx的配置使用

    1 为什么要有Connection: keep-alive? 在早期的HTTP/1.0中,每次http请求都要创建一个连接,而创建连接的过程需要消耗资源和时间,为了减少资源消耗,缩短响应时间,就需要重 ...

  7. Vue06 数据绑定

    1 Vue模板语法 Vue模板语法分为两大类,插值语法和指令语法 1.1 插值语法 1)功能:用于解析标签体内容 2)写法:{{xxx}} xxx是js表达式,且可以直接读取到vue实例里面的属性 3 ...

  8. mysql-01数据库基本简介

    1.数据库的概念 DB:数据库(database):存储数据的"仓库".它保存了一系列有组织的数据. DBMS:数据库管理系统(Database Management System ...

  9. ECharts 饼图数据放在饼图内部显示

    1.业务需求 将数据显示在饼图内部,格式化百分比显示,鼠标放上去显示具体名称和数值 原样式如下 2.业务实现 调整代码如下,核心语句已标记注释 option = { title: { text: 'R ...

  10. 线段树优化DP学习笔记 & JZOJ 孤独一生题解

    在 \(DP\) 的世界里 有一种题需要单调队列优化 \(DP\) 一般在此时,\(f_i\) 和它的决策集合 \(f_j\) 在转移时 \(i\) 不和 \(j\) 粘在一起(即所有的 \(j\) ...