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. hdu_1014(竟然真的还有更水的)

    注意输出就没了... #include<cstdio> #include<cstring> using namespace std; int gcd(int a, int b) ...

  2. Saving James Bond(dijk)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1245 Saving James Bond Time Limit: 6000/3000 MS (Java ...

  3. N的N次方

    题目描述 现给你一个正整数N,请问N^N的最左边的数字是什么? 输入 输入包含多组测试数据.每组输入一个正整数N(N<=1000000). 输出 对于每组输入,输出N^N的最左边的数字. 样例输 ...

  4. android studio升级2.3后出现的问题

    报错: Error:Execution failed for task ':app:javaPreCompileDebug'. > Annotation processors must be e ...

  5. UIScrollerview的contentsize设置

    最近被同行的一个朋友问到一个问题"UIScrollerview上添加子控件,给子控件约束好布局之后,还需要给scrollerview重新设置contentsize吗?"于是想到了我 ...

  6. 腾讯云服务器php+mysq+nginx配置出现的问题及解决方法(亲测)

    http://blog.csdn.net/hfdmv/article/details/50900043 删除文件命令 sudo rm -f /usr/share/nginx/html/home.php ...

  7. 织梦DedeCMS v5.7 实现导航条下拉菜单

    首先将下面这段代码贴到templets\default\footer.htm文件里(只要在此文件里就行,位置无所谓) <</span>script type='text/javasc ...

  8. 如何在Chrome下使用Postman进行rest请求测试

    在web和移动端开发时,常常会调用服务器端的restful接口进行数据请求,为了调试,一般会先用工具进行测试,通过测试后才开始在开发中使用.这里介绍一下如何在chrome浏览器利用postman应用进 ...

  9. php switch case语句用法

  10. Win8无法访问xp共享的解决方法——win8网上邻居访问别的xp电脑要用户名和密码取消方法

    新装win8,原来的win7正常连接xp下载机的共享,但在win8下进网上邻居却无法访问xp的共享,显示”用户名或密码不正确”,而密码明明是对的如图所示: 解决方法: 按Win+R启动运行,输secp ...