来自FallDream的博客,未经允许,请勿转载,谢谢。


设d(x)表示x的约数个数,求$\sum_{i=1}^{n}d(i^{3})$

There are 5 Input files.

- Input #1: 1≤N≤10000, TL = 1s.

- Input #2: 1≤T≤300, 1≤N≤10^8, TL = 20s.

- Input #3: 1≤T≤75, 1≤N≤10^9, TL = 20s.

- Input #4: 1≤T≤15, 1≤N≤10^10, TL = 20s.

- Input #5: 1≤T≤2, 1≤N≤10^11, TL = 20s.

$i^{3}$的约数个数$d(i^{3})$是一个积性函数,所以转而求$d(x)=\prod{F(pi^{ci})}$,其中$F ( pk ^ {ck} )=3ck+1$

可以直接洲阁筛 学了一天大概懂了 顺便抄了个模板

-----

gi表示1-i中与前j个质数互质的数字的F之和

fi表示1-i中由小于根号n的后j个质数组成的数字的F之和

容易得出转移方程 $$g[i][j]=g[i][j]-F(pk)g[\frac{i}{pk}][j-1]$$

$$ f[i][j]=f[i][j-1]+\sum_{ck>=1}F(pk^{ck})f[\frac{i}{pk^{ck}}][j]$$

显然i只有根号种取值 对于每个根号n以内的质数都要转移,复杂度$O(\frac{n}{\log n})$

考虑优化,显然$p_{j+1}>i$的时候,g[i][j]=4(3*1+1)

所以当$pj^{2}>i$的时候,g[i][j]=g[i][j-1]+F(pi) 可以不用转移,用的时候补上那一段即可。

之所以把f的状态表示成"后j个",也是出于这个目的

这样的复杂度近似是$O(\frac{n^{\frac{3}{4}}}{logn})$

然后线筛出根号n以内的F[],答案是$f[n]+\sum_{i=1}^{\sqrt{n}}F[i]g[\frac{n}{i}]$

#include<iostream>
#include<cstdio>
#include<cmath>
#define MN 320000
#define ll long long
using namespace std;
inline ll read()
{
ll x = ; char ch = getchar();
while(ch < '' || ch > '') ch = getchar();
while(ch >= '' && ch <= ''){x = x * + ch - '';ch = getchar();}
return x;
} int s[MN+],num=,last[MN+],l[MN+],l0[MN+],sq,P,N[MN+];
ll f0[MN+],f[MN+],g0[MN+],g[MN+],d[MN+],n;
bool b[MN+]; void CalcF()
{
for(int i=;i<=sq;++i) f[i]=f0[i]=;
for(int i=P-;i;--i)
{
for(int j=;j<=sq&&l[j]>i;++j)
{
ll now=(n/j)/s[i];
for(int tms=;now;now/=s[i],tms+=)
{
if(now<=sq) f[j]+=tms*(f0[now]+*(max(,N[now]-max(i+,l0[now])+)));
else f[j]+=tms*(f[n/now]+*max(,P-max(i+,l[n/now])));
}
}
for(int j=sq;j&&l0[j]>i;--j)
{
ll now=j/s[i];
for(int tms=;now;tms+=,now/=s[i])
f0[j]+=tms*(f0[now]+*max(,N[now]-max(i+,l0[now])+));
}
}
for(int i=;i<=sq;++i) f[i]+=*(P-l[i]);
} void CalcG()
{
for(int i=;i<=sq;++i)
g0[i]=i,g[i]=n/i;
for(int i=;i<P;++i)
{
for(int j=;j<=sq&&l[j]>i;++j)
{
ll now=n/j/s[i];
if(now<=sq) g[j]-=g0[now]-max(,i-l0[now]);
else g[j]-=g[n/now]-max(,i-l[n/now]);
}
for(int j=sq;j&&l0[j]>i;--j)
g0[j]-=g0[j/s[i]]-max(,i-l0[j/s[i]]);
}
for(int i=;i<=sq;++i) g[i]-=P-l[i];
} int main()
{
d[]=;
for(int i=;i<=MN;++i)
{
if(!b[i]) s[++num]=last[i]=i;
for(int j=;s[j]*i<=MN;++j)
{
b[s[j]*i]=,last[s[j]*i]=s[j];
if(i%s[j]==) break;
}
int sum=,tms,p;
for(int j=i;j>;)
{
tms=;p=last[j];
for(;j%p==;j/=p,++tms);
sum*=(tms*+);
}
d[i]=sum;
N[i]=N[i-]+(!b[i]);
}
for(int T=read();T;--T)
{
n=read();sq=sqrt(n);l[sq+]=;
for(P=;1LL*s[P]*s[P]<=n;++P);
for(int i=;i<=sq;++i)
for(l0[i]=l0[i-];1LL*s[l0[i]]*s[l0[i]]<=i;++l0[i]);
for(int i=sq;i;--i)
for(l[i]=l[i+];1LL*s[l[i]]*s[l[i]]<=n/i;++l[i]);
CalcF();CalcG();
ll ans=f[];
for(int i=;i<=sq;++i)
ans+=*d[i]*(g[i]-);
printf("%lld\n",ans);
}
return ;
}

[Spoj]Counting Divisors (cube)的更多相关文章

  1. [SPOJ20174]DIVCNT3 - Counting Divisors (cube):Min_25筛

    分析 首先,STO ywy OTZ,ywy TQL%%%! 说一下这道题用min_25筛怎么做. 容易发现,对于所有质数\(p\),都满足\(f(p)=4\),于是我们就可以直接通过\([1,x]\) ...

  2. DIVCNT2&&3 - Counting Divisors

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

  3. SPOJ 20713 DIVCNT2 - Counting Divisors (square)

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

  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. HDU 6069 Counting Divisors

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

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

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

  7. hdu 6069 Counting Divisors 筛法

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

  8. 2017 Multi-University Training Contest - Team 4 hdu6069 Counting Divisors

    地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=6069 题目: Counting Divisors Time Limit: 10000/5000 ...

  9. hdu6069 Counting Divisors 晒区间素数

    /** 题目:hdu6069 Counting Divisors 链接:http://acm.hdu.edu.cn/showproblem.php?pid=6069 题意:求[l,r]内所有数的k次方 ...

随机推荐

  1. 400多个开源项目以及43个优秀的Swift开源项目-Swift编程语言资料大合集

    Swift 基于C和Objective-C,是供iOS和OS X应用编程的全新语言,更加高效.现代.安全,可以提升应用性能,同时降低开发难度. Swift仍然处于beta测试的阶段,会在iOS 8发布 ...

  2. MySQL InnoDB锁机制

    概述: 锁机制在程序中是最常用的机制之一,当一个程序需要多线程并行访问同一资源时,为了避免一致性问题,通常采用锁机制来处理.在数据库的操作中也有相同的问题,当两个线程同时对一条数据进行操作,为了保证数 ...

  3. php的打印sql语句的方法

    echo M()->_sql(); 这样就可以调试当前生成的sql语句: //获取指定天的开始时间和结束时间 $datez="2016-05-12"; $t = strtot ...

  4. markdown最基本的几种语法

    1.标题 # 相当于<h1></h1> ## 相当于<h2></h2> ### 相当于<h3></h3> #### 相当于< ...

  5. 【转】optach学习

    [转自:https://yq.aliyun.com/articles/28007,仅作学习用途] 摘要: Opatch 是oracle公司开发的安装,卸载,检测patch冲突的工具,管理oracle所 ...

  6. linux下的Shell编程(7)使用-x和-n调试shell程序

    我们也可以在Shell下调试Shell Script脚本,当然最简单的方法就是用echo输出查看变量取值了.Bash也提供了真正的调试方法,就是执行脚本的时候用-x参数. sh -x filename ...

  7. Linux后台运行命令 nohup command > myout.file 2>&1

    Linux命令后台运行 转自北国的雨,谢谢:http://www.cnblogs.com/lwm-1988/archive/2011/08/20/2147299.html 有两种方式:1. comma ...

  8. python JavaScript

    JavaScript 一. JavaScript Javascript 在开发中绝大多数情况是基于对象的.也是面向对象的. a. JavaScript的引入方式 1 2 3 4 5 6 7 #直接编写 ...

  9. python基础——生成器表达式

    生成器表达式 1 生成器表达式定义 生成器表达式并不真正的创建数字列表,而是返回一个生成器对象,此对象在每次计算出一个条目后,把这个条目"产生"(yield)出来.生成器表达式使用 ...

  10. Windows10下的docker安装与入门 (三) 创建自己的docker镜像并且在容器中运行它

    Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化.容器是完全使用沙箱机制,相互之间不会有任何 ...