SPOJ DIVCNT2 - Counting Divisors (square)

题意:求

\[\sum_{i=1}^n\sigma_0(i^2)
\]


好棒啊!

带着平方没法做,考虑用其他函数表示\(\sigma_0(i^2)\),把平方消去。

\(\sigma_0(n) = (1*1)(n) = \sum_{d\mid n}1\)

我们考虑那些\(n^2\)有而\(n\)没有的因子,\(n=\prod p_i^{a_i}\),那么这些因子里一定有\(p_i^c:c>a_i\)。

对于因子\(d\),他的每个质因子都可以指数加上\(a_i\)成为\(n^2\)独有的因子,贡献为\(2^{\omega(d)}\),其中\(\omega(n)\)表示不同的质因子个数。

\(2^{\omega(n)} = \sum_{d\mid n}\mu^2(d)\)

\[\sigma_0(n^2) = \sum_{d\mid n} 2^{\omega(d)} = \sum_{d\mid n} \sum_{e\mid d} \mu^2(e) = ((\mu^2 * 1) * 1) (n)
\]

我们就是要求\((\mu * 1) * 1 = \mu * (1*1) = \mu * \sigma_0\)的前缀和

\[\begin{align}
ans &= \sum_{i=1}^n \sum_{d\mid i} \mu^2(d) \cdot \sigma_0(\frac{i}{d}) \\
&= \sum_{i=1}^n \mu^2(i) \sum_{j=1}^{\lfloor \frac{n}{i} \rfloor} \sigma_0(j)
\end{align}
\]

不用杜教筛,我们也可以求。

我们只要得到\(\mu^2\)和\(\sigma_0\)的前缀和就可以整除分块了。

\(\sum_{i=1}^n \mu^2(i) = \sum_{i=1}^{\sqrt{n}}\mu(i)\lfloor \frac{n}{i^2} \rfloor\) 就是无平方因子数的个数呀

\(\sum_{i=1}^n\sigma_0(i) = \sum_{i=1}^n \lfloor \frac{n}{i} \rfloor\) 也可以整除分块

同时我们使用线性筛预处理前\(O(n^{\frac{2}{3}})\)的前缀和,剩下的部分用上面两个式子\(O(\sqrt{n})\)计算

复杂度分析和杜教筛类似,

\[T(n) =O(k + \sum_{i=1}^{\frac{n}{k}}\sqrt{\frac{n}{i}})=O(k + \frac{n}{\sqrt{k}})
\]

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
const int N=1e8+5;
int U=1e8;
inline ll read(){
char c=getchar(); ll x=0,f=1;
while(c<'0' || c>'9') {if(c=='-')f=-1; c=getchar();}
while(c>='0' && c<='9') {x=x*10+c-'0'; c=getchar();}
return x*f;
} bool notp[N]; int p[N/10], mu[N], lp[N], mu2[N]; ll si[N];
void sieve(int n) {
mu[1]=1; si[1]=1; mu2[1]=1;
for(int i=2; i<=n; i++) {
if(!notp[i]) p[++p[0]] = i, mu[i] = -1, si[i] = lp[i] = 2;
for(int j=1; j <= p[0] && i*p[j] <= n; j++) {
int t = i*p[j];
notp[t] = 1;
if(i%p[j] == 0) {
mu[t] = 0;
lp[t] = lp[i] + 1;
si[t] = si[i] / lp[i] * lp[t];
break;
}
mu[t] = -mu[i];
lp[t] = 2;
si[t] = si[i] * 2;
}
mu2[i] = mu2[i-1] + mu[i] * mu[i];
si[i] += si[i-1];
}
} inline ll sum_mu2(ll n) {
if(n <= U) return mu2[n];
int m = sqrt(n); ll ans=0;
for(int i=1; i<=m; i++) if(mu[i]) ans += mu[i]>0 ? (n / ((ll)i*i)) : -(n / ((ll)i*i));
return ans;
}
inline ll sum_si(ll n) {
if(n <= U) return si[n];
ll ans=0, r;
for(ll i=1; i<=n; i=r+1) {
r = n/(n/i);
ans += (r-i+1) * (n/i);
}
return ans;
} ll solve(ll n) {
ll ans=0, r, last=0, now;
for(ll i=1; i<=n; i=r+1, last=now) {
r = n/(n/i); //printf("begin %lld\n", r);
now = sum_mu2(r); //printf("[%lld, %lld]\n", i, r);
ans += (now - last) * sum_si(n/i);
}
return ans;
} ll q[10005], mx;
int main() {
freopen("in", "r", stdin);
int T=read();
for(int i=1; i<=T; i++) q[i]=read(), mx = max(mx, q[i]);
U = pow(mx,2/3.0);
if(mx >= 1e6 && mx <= 1e8+1) U=1e8;
sieve(U);
for(int i=1; i<=T; i++) printf("%lld\n", solve(q[i]));
}

SPOJ DIVCNT2 [我也不知道是什么分类了反正是数论]的更多相关文章

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

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

  2. SPOJ DIVCNT2

    SPOJ DIVCNT2 题目大意: 求\(S2(n)=\sum_{i=1}^{n}\sigma_0{(i^2)}\) . 题解 我们可以先考虑括号里只有一个\(i\)的情况,这样,我们把\(i\)分 ...

  3. 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&= ...

  4. [SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)

    题目 vjudge URL:Counting Divisors (square) Let σ0(n)\sigma_0(n)σ0​(n) be the number of positive diviso ...

  5. [原]CentOS7.2最小安装环境部署Asp.NET Core笔记

    转载请注明原作者(think8848)和出处(http://think8848.cnblogs.com) 写在前面的话 不知不觉在cnblogs上注册已经10多年了,看我的园龄就直接暴露了我实际年龄, ...

  6. ionic overflow:auto失效

    事情的起因是 同事上传一个很宽的table文件,因为手机屏幕宽度有限,因此要求 用户可以水平滚动页面,这样table的内容通过滚动就可以实现啦. 当时感觉很简单 给table外面的容器加个overfl ...

  7. noip2002提高组题解

    再次280滚粗.今天早上有点事情,所以做题的时候一直心不在焉,应该是三天以来状态最差的一次,所以这个分数也还算满意了.状态真的太重要了. 第一题:均分纸牌 贪心.(昨天看BYVoid的noip2001 ...

  8. (原)DropBlock A regularization method for convolutional networks

    转载请注明出处: https://www.cnblogs.com/darkknightzh/p/9985027.html 论文网址: https://arxiv.org/abs/1810.12890 ...

  9. 【游记】CCHO TY国初划水记

    没想到第一篇游记竟然是化学国初(其实是上次SXACM时候懒得写 DAY0 一下午做了5个小时的校车,服务区水真贵 肝了4个小时模拟题,颠到崩溃. 下榻在距离山大附不远的一个酒店,高三人好多哇,我们年级 ...

随机推荐

  1. pycharm中一直跳出updating indices...indexing

    直接比较明显的就是cpu直冲天际. pycharm是一款用了就不愿意换的ide,因为他的功能十分强大,同时也有着让人诟病的问题,就是他功能太全了,以至于有的功能你这辈子可能都不会去触碰,带来的直接问题 ...

  2. 科普:String hashCode 方法为什么选择数字31作为乘子

    1. 背景 某天,我在写代码的时候,无意中点开了 String hashCode 方法.然后大致看了一下 hashCode 的实现,发现并不是很复杂.但是我从源码中发现了一个奇怪的数字,也就是本文的主 ...

  3. .26-浅析webpack源码之事件流make(1)

    compilation事件流中,依然只是针对细节步骤做事件流注入,代码流程如图: // apply => this-compilation // apply => compilation ...

  4. window.top.location.href 和 window.location.href 的区别

    window.location.href 是本页面跳转 window.top.location.href是最外层的页面跳转

  5. destoon 开启邮箱

  6. 为什么要进行URL编码

    我们都知道Http协议中参数的传输是"key=value"这种简直对形式的,如果要传多个参数就需要用“&”符号对键值对进行分割.如"?name1=value1&a ...

  7. Struts的session问题

    问题描述: 在一个action中设置session之后,在jsp中得不到session的值或者在另一个action中得不到session的值. 解决方案: 1.不要把session设置成为静态的,同时 ...

  8. Spring的RestTemplata使用

    spring-web的RestTemplata是对java底层http的封装,使用RestTemplata用户可以不再关注底层的连接建立,并且RestTemplata不仅支持Rest规范,还可以定义返 ...

  9. Android 双卡获取当前使用流量在线卡的信息

    最近接触了一个项目,需要获取在线流量卡的信息,下面的方式,可以获取大部分手机的正确手机卡信息. 一  获取获取IMEI public static String getDeviced(int solt ...

  10. FPGA上如何求32个输入的最大值和次大值:分治

    上午在论坛看到个热帖,里头的题目挺有意思的,简单的记录了一下. 0. 题目 在FPGA上实现一个模块,求32个输入中的最大值和次大值,32个输入由一个时钟周期给出.(题目来自论坛,面试题,如果觉得不合 ...