SPOJ:[DIVCNT3]Counting Divisors



题目大意:求1~N的每个数因子数的立方和。
题解:由于N过大,我们不能直接通过线性筛求解。我们可以采用洲阁筛。
洲阁筛的式子可以写成:

对于F(1~√n),可以直接线性筛求解。
对于
,我们进行以下DP:
g[i][j]为1~j中,与前i个质数互质的数的F值之和。
dp过程中,有
如果p[i]>j,则g[i][j]=F(1);
如果p[i]*p[i]>j>=p[i],则g[i][j]=g[i-1][j]-p[i]^k*F(1)=g[d][j]-(p[d+1]^k~p[i]^k)*F(1),其中p[d]为最大的p[d]*p[d]<=j的质数;
如果j>=p[i]*p[i],我们老老实实调用式子。
对于
,我们用类似的方式DP:
f[i][j]为1~j中,只以第i个到第m个质数为质因子的数的F值之和(m为√N以内质数个数)。
类似的,dp过程中,有
如果p[i]>j,则f[i][j]=F(1);
如果p[i]*p[i]>j>=p[i],则f[i][j]=f[i+1][j]+F(p[i])*F(1)=F(1)+F(p[i]~p[e])*F(1),其中p[e]为最大的p[e]<=j的质数;
如果j>=p[i]*p[i],我们老老实实调用式子。
代码:
#include<bits/stdc++.h>
using namespace std;
long long block,n,lb[],dp[],zs[],ans[],ans2;
bool bo[],bo2[];
int dp2[],dp3[],m,mm,tot,j,bo3[],tt;
void xxs(int n)
{
ans[]=;
for(int i=;i<=n;i++)
{
if(bo[i]==){ mm++; zs[mm]=i; ans[i]=; bo2[i]=; bo3[i]=; }
for(int j=;j<=mm;j++)
if(zs[j]*i>n)break;else
if(i%zs[j]==)
{
if(bo2[i]==)bo2[i*zs[j]]=; bo3[i*zs[j]]=bo3[i]+; ans[i*zs[j]]=ans[i]/bo3[i]*(bo3[i]+);
bo[i*zs[j]]=; break;
}else { ans[i*zs[j]]=ans[i]*; bo[i*zs[j]]=; bo3[i*zs[j]]=; }
}
}
int dy(long long x){ if(x<=block)return x;else return tot-n/x+; }
long long get(int i,int j)
{
if(dp2[j]==i)return dp[j];else
if(lb[j]<zs[i]){ if(j>)return ; return ; }
return dp[j]-i+dp2[j];
}
long long get2(int i,int j)
{
if(dp2[j]==i)return dp[j];else
if(lb[j]<zs[i])return ;
return (dp3[j]-i+)*+;
}
int main()
{
scanf("%d",&tt); xxs();
for(int ii=;ii<=tt;ii++)
{
scanf("%lld",&n); block=(int)sqrt(n); ans2=;
for(m=;m<=mm;m++)if(zs[m]>block)break; m--; tot=;
for(int i=;i<=block;i++){ lb[++tot]=i; if(1ll*i*i<n)lb[++tot]=n/i; }
sort(lb+,lb+tot+);
for(int i=;i<=tot;i++)dp[i]=lb[i],dp2[i]=;
for(int i=;i<=m;i++)
{
for(int j=tot;j>=;j--)
{
if(lb[j]<zs[i]*zs[i])break; dp2[j]=i;
dp[j]=dp[j]-get(i-,dy(lb[j]/zs[i]));
}
}
for(int i=;i<=block;i++)
ans2=ans2+ans[i]*(get(m,tot-i+)-)*;
j=;
for(int i=;i<=tot;i++)
{
dp[i]=; dp2[i]=m+;
while((j<=m)and(zs[j]<=lb[i]))j++; dp3[i]=j-;
}
for(int i=m;i>=;i--)
{
for(int j=tot;j>=;j--)
{
if(lb[j]<zs[i]*zs[i])break; dp[j]=get2(i+,j); dp2[j]=i;
long long t=j,l=;
while(lb[t]>=zs[i])
{
t=dy(lb[t]/zs[i]); l+=;
dp[j]=dp[j]+l*get2(i+,t);
}
}
}
ans2=ans2+get2(,tot);
printf("%lld\n",ans2);
}
}
SPOJ:[DIVCNT3]Counting Divisors的更多相关文章
- [SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)
题目 vjudge URL:Counting Divisors (square) Let σ0(n)\sigma_0(n)σ0(n) be the number of positive diviso ...
- 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&= ...
- [SPOJ20174]DIVCNT3 - Counting Divisors (cube):Min_25筛
分析 首先,STO ywy OTZ,ywy TQL%%%! 说一下这道题用min_25筛怎么做. 容易发现,对于所有质数\(p\),都满足\(f(p)=4\),于是我们就可以直接通过\([1,x]\) ...
- DIVCNT2&&3 - Counting Divisors
DIVCNT2 - Counting Divisors (square) DIVCNT3 - Counting Divisors (cube) 杜教筛 [学习笔记]杜教筛 (其实不算是杜教筛,类似杜教 ...
- SPOJ 20713 DIVCNT2 - Counting Divisors (square)
DIVCNT2 - Counting Divisors (square) #sub-linear #dirichlet-generating-function Let \sigma_0(n)σ0 ...
- HDU 6069 Counting Divisors
Counting Divisors Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Oth ...
- 杜教筛进阶+洲阁筛讲解+SPOJ divcnt3
Part 1:杜教筛进阶在了解了杜教筛基本应用,如$\sum_{i=1}^n\varphi(i)$的求法后,我们看一些杜教筛较难的应用.求$\sum_{i=1}^n\varphi(i)*i$考虑把它与 ...
- hdu 6069 Counting Divisors(求因子的个数)
Counting Divisors Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Oth ...
- hdu 6069 Counting Divisors 筛法
Counting Divisors Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Oth ...
随机推荐
- (二)Django连接本地mysql异常
Pycharm连接数据库出现错误 管理员身份进入mysql数据库 命令: mysql -u root -p 重新进入mysql 在进入Pycharm发现连接成功
- C++中的delete加深认识
delete操作: 我们在删除一个指针之后,编译器只会释放该指针所指向的内存空间,而不会删除这个指针本身. 1.假如你不去释放,那么该区域的内存始终不能被其他数据所使用.2.指向该内存的指针是个局部变 ...
- 从文本文件hello.txt到可执行文件hello
第一阶段 使用编辑器编写的源代码 (.txt) 文件 hello.c.经过 Pre-processor 进行前处理.在前处理阶段,当 pre-processor 读到代码中的#include<s ...
- leetcode-12双周赛-1246-删除回文子数组
题目描述: 方法:区间dp O(N^3) class Solution: def minimumMoves(self, A: List[int]) -> int: N = len(A) dp = ...
- 【Flutter学习】基本组件之文本组件Text
一,概述 文本组件(Text)负责显示文本和定义显示样式, 二,继承关系 Object > Diagnosticable > DiagnosticableTree > Widget ...
- list 链表
#include <list> #include <iostream> using std::list; /* 双向环状链表 //每一个结点 一个数据域 一个前驱指针 一个后驱 ...
- jdk环境配置-windows 10
近期由于云服务器到期,重新买了一个云服务器,这里顺便把jdk环境配置步骤做一个记录 1.下载自己需要的jdk 我这里是下的免安装版的 2.计算机(此电脑)->属性->高级系统设置-> ...
- js读取json数据
{ "code": 0, "msg": null, "data": { "pageNum": 1, "page ...
- prototype.原型链.原型链图
//1.几乎所有函数都有prototype属性,这个是个指针,指向原型对象;Function.prototype这个没有 //2.所有对象中都有__proto__属性.(Object.protot ...
- 牛客 判断t1树中是否含有与t2树拓扑结构完全相同的子树
题目链接:https://www.nowcoder.com/practice/5a41ce17e8194e1688aa83a73137f7ee?tpId=101&tqId=33239& ...