题解[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. 数据预处理时为什么要使用OneHot编码?

    什么是LabelEncoder(整数编码) 整数编码 将一列文本数据转化成数值,即列中的每一个特征都通过一个整数来表示.例如,[red, blue, red, yellow] = [0,2,0,1]. ...

  2. BUG日记---SSM进行多表查询错误-----页面使用<c:foreach>错误

    javax.servlet.ServletException: javax.servlet.jsp.JspTagException: Don't know how to iterate over su ...

  3. Mybatis的学习与理解

    Mybatis 1.介绍 Mybatis是支持SQL查询,存储和映射的持久层框架.使用时消除了JDBC代码和参数的设置以及对结果集的封装 Mybatis可以使用注解来进行配置和进行映射,将Mapper ...

  4. OuputStreamWriter介绍-OuputStreamReader介绍

    OuputStreamWriter介绍 java.io.Outputstreamlwriter extends writeroutputStreamwriter:是字符流通向字节流的桥梁:可使用指定的 ...

  5. Java进阶 P-2.1+P-2.2

    对象的识别 对于Java而言,要识别两个对象是否为同一个对象有两种方式: 一是根据内存地址识别("=="号 识别) 二是根据equals() .hasCode()方法识别(默认比较 ...

  6. Java 入门与进阶P-7.1+P-7.2

    函数的定义 函数的定义 习惯把函数也叫成方法,都是一个意思:函数是具备特定功能的一段代码块,解决了重复性代码的问题. 为什么要定函数呢? 目的是为了提高程序的复用性和可读性. 函数的格式 修饰符返回值 ...

  7. 静态static关机子修饰成员方法-静态static的内存图

    静态static关机子修饰成员方法 静态方法 当 static 修饰成员方法时,该方法称为类方法 .静态方法在声明中有 static ,建议使用类名来调用,而不需要 创建类的对象.调用方式非常简单. ...

  8. petite-vue和Vue的比较

    petite-vue不止是变得更小,它还是渐进式增强的最佳实践. Vue不构建或构建都能使用.当通过构建使用时(例如使用单文件组件),Vue预编译所有的模板,所以运行时没有再处理模板.多亏了树摇(th ...

  9. 搭个ChatGPT算法模型,离Java程序员有多远?

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 最近 ChatGPT 很火,火到了各行各业.记得去年更多的还是码农最新体验后拿它搜代码,现在各 ...

  10. 计算机网络14 Internet网络层主要功能 IP协议 路由协议 ICMP协议

    1 主机.路由器网络层主要功能 2 IP数据报 2.1 图示 2.2 字段详细介绍 1)版本号 占4位:IP协议的版本号.4表示IPv4,6表示IPv6. 2)首部长度 占4位:表示IP分组首部长度. ...