题目

vjudge URL:Counting Divisors (square)

Let σ0(n)\sigma_0(n)σ0​(n) be the number of positive divisors of nnn.

For example, σ0(1)=1\sigma_0(1) = 1σ0​(1)=1, σ0(2)=2\sigma_0(2) = 2σ0​(2)=2 and σ0(6)=4\sigma_0(6) = 4σ0​(6)=4.

Let S2(n)=∑i=1nσ0(i2).S_2(n) = \sum _{i=1}^n \sigma_0(i^2).S2​(n)=i=1∑n​σ0​(i2).

Given NNN, find S2(N)S_2(N)S2​(N).

Input

First line contains TTT (1≤T≤100001 \le T \le 100001≤T≤10000), the number of test cases.

Each of the next TTT lines contains a single integer NNN. (1≤N≤10121 \le N \le 10^{12}1≤N≤1012)

Output

For each number NNN, output a single line containing S2(N)S_2(N)S2​(N).

Example
  • Input

5

1

2

3

10

100

  • Output

1

4

7

48

1194

  • Explanation for Input

        S2(3)=σ0(12)+σ0(22)+σ0(32)=1+3+3=7~~~~S_2(3) = \sigma_0(1^2) + \sigma_0(2^2) + \sigma_0(3^2) = 1 + 3 + 3 = 7    S2​(3)=σ0​(12)+σ0​(22)+σ0​(32)=1+3+3=7
Information

There are 6 Input files.

  • Input #1: 1≤N≤100001 \le N \le 100001≤N≤10000, TL = 1s.
  • Input #2: 1≤T≤800, 1≤N≤1081 \le T \le 800,\ 1 \le N \le 10^{8}1≤T≤800, 1≤N≤108, TL = 20s.
  • Input #3: 1≤T≤200, 1≤N≤1091 \le T \le 200,\ 1 \le N \le 10^{9}1≤T≤200, 1≤N≤109, TL = 20s.
  • Input #4: 1≤T≤40, 1≤N≤10101 \le T \le 40,\ 1 \le N \le 10^{10}1≤T≤40, 1≤N≤1010, TL = 20s.
  • Input #5: 1≤T≤10, 1≤N≤10111 \le T \le 10,\ 1 \le N \le 10^{11}1≤T≤10, 1≤N≤1011, TL = 20s.
  • Input #6: T=1, 1≤N≤1012T = 1,\ 1 \le N \le 10^{12}T=1, 1≤N≤1012, TL = 20s.

My C++ solution runs in 5.3 sec. (total time) //呵呵

Source Limit is 6 KB.*

题目分析

σ0(n)\sigma_0(n)σ0​(n)表示nnn的约数个数,即求

∑i=1nσ0(i2)\large \sum_{i=1}^n
\sigma_0(i^2)i=1∑n​σ0​(i2)

1&lt;=n&lt;=10121&lt;=n&lt;=10^{12}1<=n<=1012

前言
  • mdzz,写了1h的Latex公式没保存。。因为机房电脑的烂CPU,本地测这道题的极限数据时崩溃了c
  • 这道题是真的卡常,最后点线性筛必须筛到很大,5e7能过,1e7、2e7都不行(可能因为我是大常数选手吧,悄悄打上卡常的FLAG)
  • 本地评测炸电脑,真的无语。。
  • 刚开始模了1e9+7 WA了好久。。。
  • 由于是求函数前缀和,又和杜教筛的题一起做的,就放在杜教筛/莫比乌斯反演里吧
正文

设n=∏i=1kpiai\large n=\prod_{i=1}^kp_i^{a_i}n=∏i=1k​piai​​

则σ0(n2)=∏i=1k(2ai+1)=∑S∈{1,2,...,k}2∣S∣⋅∏i∈Sai\large \sigma_0(n^2)=\prod_{i=1}^k(2a_i+1)\\=\sum_{S\in\{1,2,...,k\}}2^{|S|}\cdot\prod_{i\in S}a_iσ0​(n2)=i=1∏k​(2ai​+1)=S∈{1,2,...,k}∑​2∣S∣⋅i∈S∏​ai​

将∏i∈Sai\prod_{i\in S}a_i∏i∈S​ai​看作是 只由S内的下标所对应的素数\color{blue}S内的下标所对应的素数S内的下标所对应的素数(乘起来)构成的nnn的约数的个数,因为每一个约数都对答案造成了对应的2∣S∣2^{|S|}2∣S∣的贡献,那么

σ0(n2)=∑d∣n2ω(d)\large \sigma_0(n^2)=\sum_{d|n}2^{\omega(d)}σ0​(n2)=d∣n∑​2ω(d)其中ω(d)\omega(d)ω(d)表示d的质因子的个数(想想)

与此同时,我们又发现2ω(d)2^{\omega(d)}2ω(d)实质上是ddd的质因子选或不选的方案数,也就是nnn的无平方因子的约数的个数,则

σ0(n2)=∑d∣n∑k∣d∣μ(k)∣\large \sigma_0(n^2)=\sum_{d|n}\sum_{k|d}|\mu(k)|σ0​(n2)=d∣n∑​k∣d∑​∣μ(k)∣因为根据μ\muμ函数的定义,只有无平方因子数的函数值才为111或−1-1−1,加上绝对值就相当于统计了个数(有的题解也写的是μ(k)2\mu(k)^2μ(k)2,个人认为第一眼看到这个平方会懵一会)

∑i=1nσ0(i2)=∑i=1n∑d∣i∑k∣d∣μ(k)∣=∑k=1n∣μ(k)∣∑k∣d∑d∣i1=∑k=1n∣μ(k)∣∑k∣d⌊nd⌋=∑k=1n∣μ(k)∣∑d=1⌊nk⌋⌊ndk⌋=∑k=1n∣μ(k)∣∑d=1⌊nk⌋⌊⌊nk⌋d⌋=∑k=1n∣μ(k)∣∑d=1⌊nk⌋⌊⌊nk⌋d⌋\large \sum_{i=1}^n\sigma_0(i^2)=\sum_{i=1}^n\sum_{d|i}\sum_{k|d}|\mu(k)|\\=\sum_{k=1}^n|\mu(k)|\sum_{k|d}\sum_{d|i}1\\=\sum_{k=1}^n|\mu(k)|\sum_{k|d}\lfloor\frac nd\rfloor\\=\sum_{k=1}^n|\mu(k)|\sum_{d=1}^{\lfloor\frac nk\rfloor}\lfloor\frac n{dk}\rfloor\\=\sum_{k=1}^n|\mu(k)|\sum_{d=1}^{\lfloor\frac nk\rfloor}\lfloor\frac {\lfloor\frac nk\rfloor}d\rfloor\\=\sum_{k=1}^n|\mu(k)|\sum_{d=1}^{\lfloor\frac nk\rfloor}\lfloor\frac {\lfloor\frac nk\rfloor}d\rfloori=1∑n​σ0​(i2)=i=1∑n​d∣i∑​k∣d∑​∣μ(k)∣=k=1∑n​∣μ(k)∣k∣d∑​d∣i∑​1=k=1∑n​∣μ(k)∣k∣d∑​⌊dn​⌋=k=1∑n​∣μ(k)∣d=1∑⌊kn​⌋​⌊dkn​⌋=k=1∑n​∣μ(k)∣d=1∑⌊kn​⌋​⌊d⌊kn​⌋​⌋=k=1∑n​∣μ(k)∣d=1∑⌊kn​⌋​⌊d⌊kn​⌋​⌋

  • 先看第二个∑\large\sum∑,对于某一个⌊nk⌋\large{\lfloor\frac nk\rfloor}⌊kn​⌋的取值,把它记作NNN,就以NNN的范围做整除分块优化,Θ(N)\large\Theta(\sqrt N)Θ(N​)的时间复杂度,那么外层还有一个求和,于是在外面也套一层整除分块优化,预处理出前n23\large n^{\frac 23}n32​后时间复杂度为Θ(n23)\large\Theta(n^{\frac23})Θ(n32​)

    • 此处预处理为线性筛,考虑变换,∑i=1n⌊ni⌋\large\sum_{i=1}^n\large{\lfloor\frac ni\rfloor}∑i=1n​⌊in​⌋实际可看作枚举iii后看nnn以内有多少个数能被iii整除,这不就是∑i=1nσ0(i)\large\sum_{i=1}^n\sigma_0(i)∑i=1n​σ0​(i)吗?

      于是我们只需要筛出约数个数在累加就行了,线性筛时存一下当前数的最小质因子的次数就可以愉快的线性筛了
  • 由于在外面一层套上了整除分块优化,则需要求出∣μ(k)∣\large |\mu(k)|∣μ(k)∣的前缀和,也就是nnn以内的无平方因子数
    • 这里处理无平方因子数时用容斥原理,有

      ∑i=1n∣μ(i)∣=∑i=1nμ(i)⋅⌊ni2⌋\large\sum_{i=1}^n|\mu(i)|=\sum_{i=1}^{\sqrt n}\mu(i)\cdot\lfloor\frac n{i^2}\rfloori=1∑n​∣μ(i)∣=i=1∑n​​μ(i)⋅⌊i2n​⌋想想μ\muμ函数的定义,这个容斥还是比较好理解的

      Θ(n)\large \Theta(\sqrt n)Θ(n​)可处理出来

综上,各种操作之后把时间复杂度降到了Θ(n23)\large\Theta(n^{\frac 23})Θ(n32​)

等等,真的降到了吗??!看看降到Θ(n23)\large\Theta(n^{\frac 23})Θ(n32​)的条件?

  • 预处理出前n23\large n^{\frac 23}n32​

然而1&lt;=n&lt;=10121&lt;=n&lt;=10^{12}1<=n<=1012(掀桌)

所以只能尽可能的接近,实测5e75e75e7能过,2e72e72e7都会TLE

CAUTION

首先做这道题,如果电脑是机房的老电脑/旧电脑/烂电脑,不要像作死去测什么101210^{12}1012的极限数据,反正我是卡爆了(逃)

也不要像我一样边写代码边写博客,更不要卡住之后作死的乱点一气把浏览器搞炸了,我写了1h1h1h的LatexLatexLatex啊!!!(这里的公式已经是精简版了)

最后一句忠告,写博客多按保存(富文本编辑器似乎会过一会就自动保存一下,不过不能写数学公式),写代码也是…

AC code
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
typedef long long LL;
const int MAXN = 5e7 + 1;//!!!
int Prime[MAXN], mu[MAXN], d[MAXN], Min_a[MAXN], Cnt;
bool IsnotPrime[MAXN];
LL sum_d[MAXN], sum_mu[MAXN];
void init(int n)//线性筛,Min_a[i]存的是i最小质因子的次数
{
d[1] = mu[1] = 1;
for(int i = 2; i <= n; ++i)
{ if(!IsnotPrime[i])
Prime[++Cnt] = i, mu[i] = -1, d[i] = 2, Min_a[i] = 1;
for(int j = 1, v; j <= Cnt && i * Prime[j] <= n; ++j)
{
v = i * Prime[j];
IsnotPrime[v] = 1; Min_a[v] = 1;
if(i % Prime[j] == 0)
{
Min_a[v] += Min_a[i];
mu[v] = 0;
d[v] = d[i] / Min_a[v] * (Min_a[v] + 1);
break;
}
mu[v] = -mu[i];
d[v] = d[i]<<1;
}
}
for(int i = 1; i <= n; ++i)
sum_d[i] = sum_d[i-1] + d[i],
sum_mu[i] = sum_mu[i-1] + mu[i]*mu[i];
}
inline LL Sum_mu(LL n)//莫比乌斯函数的绝对值的前缀和/[1,n]无平方因子数个数
{
if(n < MAXN) return sum_mu[n];
LL ret = 0;
for(LL i = 1; i*i <= n; ++i)
ret += mu[i] * (n/(i*i));
return ret;
}
inline LL Sum_d(LL n) //约数个数前缀和
{
if(n < MAXN) return sum_d[n];
LL ret = 0;
for(LL i = 1, j; i <= n; i=j+1)
{
j = n/(n/i);
ret += (n/i) * (j-i+1);
}
return ret;
} inline LL solve(LL n)
{
LL ret = 0;
for(LL i = 1, j; i <= n; i=j+1)
{
j = n/(n/i);
ret += (Sum_mu(j)-Sum_mu(i-1)) * Sum_d(n/i);
}
return ret;
} int main ()
{
LL T, n;
scanf("%lld", &T);
init(T > 800 ? 10000 : MAXN-1); //优化
while(T--)
{
scanf("%lld", &n);
printf("%lld\n", solve(n));
}
}

参见 传送门:大佬博客









再次吐槽数学公式的难打

[SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)的更多相关文章

  1. SPOJ : DIVCNT2 - Counting Divisors (square)

    设 \[f(n)=\sum_{d|n}\mu^2(d)\] 则 \[\begin{eqnarray*}\sigma_0(n^2)&=&\sum_{d|n}f(d)\\ans&= ...

  2. SPOJ 20713 DIVCNT2 - Counting Divisors (square)

    DIVCNT2 - Counting Divisors (square) #sub-linear #dirichlet-generating-function Let \sigma_0(n)σ​0​​ ...

  3. SP20173 DIVCNT2 - Counting Divisors (square)

    Refer 主要思路参考了 Command_block 的题解. Description 给定 \(n\)(\(n\le 10^{10}\)),求 \[\sum_{i=1}^n\sigma_0(i^2 ...

  4. hdu 6069 Counting Divisors(求因子的个数)

    Counting Divisors Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Oth ...

  5. SPOJ:[DIVCNT3]Counting Divisors

    题目大意:求1~N的每个数因子数的立方和. 题解:由于N过大,我们不能直接通过线性筛求解.我们可以采用洲阁筛. 洲阁筛的式子可以写成: 对于F(1~√n),可以直接线性筛求解. 对于,我们进行以下DP ...

  6. 【胡策篇】题解 (UOJ 192 + CF938G + SPOJ DIVCNT2)

    和泉纱雾与烟花大会 题目来源: UOJ 192 最强跳蚤 (只改了数据范围) 官方题解: 在这里哦~(说的很详细了 我都没啥好说的了) 题目大意: 求树上各边权乘积是完全平方数的路径数量. 这种从\( ...

  7. SPOJ DIVCNT2 [我也不知道是什么分类了反正是数论]

    SPOJ DIVCNT2 - Counting Divisors (square) 题意:求 \[ \sum_{i=1}^n\sigma_0(i^2) \] 好棒啊! 带着平方没法做,考虑用其他函数表 ...

  8. DIVCNT2&&3 - Counting Divisors

    DIVCNT2 - Counting Divisors (square) DIVCNT3 - Counting Divisors (cube) 杜教筛 [学习笔记]杜教筛 (其实不算是杜教筛,类似杜教 ...

  9. 【[SDOI2015]约数个数和】

    慢慢化柿子吧 要求的是这个 \[\sum_{i=1}^N\sum_{j=1}^Md(ij)\] 神奇的约数个数函数有一个这样的性质 \[d(ij)=\sum_{x|i}\sum_{y|j}[(x,y) ...

随机推荐

  1. SQL语句报错:Incorrect string value: '\xE9\x98\xBF\xE6\x96\xAF...'

    很明显是编码的问题.检查了一下$conn->query("set names utf8");已经加在代码里了.那莫非是数据库编码不是utf8? 看了一下 还真不是 于是右键要 ...

  2. Linux基础(02)MakeFile的创建和使用

    makefile是生成文件的脚本 , 把当前文件下的.c文件生成.o文件和可执行程序 SRC = $(wildcard *.c) OBJS = $(patsubst %.c,%.o,$(SRC)) C ...

  3. DS AVL树详解

    先说说二叉搜索树: 是有序的二叉树,根值>左节点值,右节点值>根值. 如果要查找某个值,二叉搜索树和二分查找一样,每进行一次值比较,就会减少一半的遍历区间. 但是,如果树插入的值一直递增/ ...

  4. 高并发 多线程批量ping工具 nbping简介和使用

    nbping 简介 nbping是为解决局域网大批量IP实例或主机探活,采用go协程并发处理,可以自定义并发的协程数量和输出结果.效率远高于现有的批量ping工具. nbping具备如下特性 - 支持 ...

  5. ALV报表——发送Excel报表邮件

    ABAP发送报表邮件 运行效果: 代码: *&---------------------------------------------------------------------* *& ...

  6. nginx通过自定义header属性来转发不同的服务

    一.背景 因为需要上线灰度发布,只要nginx接收到头部为: wx_unionid: 就会跳转到另外一个url,比如: 通过配置nginx 匹配请求头wx_unionid 来转发到灰度环境.核心:客户 ...

  7. 移动端开发rem布局之less+媒体查询布局的原理步骤和心得

    rem即是以html文件中font-size的大小的倍数rem布局的原理:通过媒体查询设置不同屏幕宽度下的html的font-size大小,然后在css布局时用rem单位取代px,从而实现页面元素大小 ...

  8. C# 快捷键(总结)

    C# 展开和折叠代码的快捷键 VS2005代码编辑器的展开和折叠代码确实很方便和实用.以下是展开代码和折叠代码所用到的快捷键,很常用: Ctrl + M + O: 折叠所有方法 Ctrl + M +  ...

  9. dump net core windbg 安装

    安装 1.下载工具windbg 地址:https://www.microsoft.com/zh-cn/p/windbg-preview/9pgjgd53tn86?SilentAuth=1&rt ...

  10. 利用vba实现excel表格连接打印编号(一页两个编号),编号支持前缀

    先看一下excel文件, 下图左边部分为文件签审单为要打印的内容, 要求一页需要打印两个文件签审单, NO需要根据打印页面连续编号, 右边部分为打印设置,以及vba部分代码展示, 打印设置可以设置打印 ...