先定义几个符号:

[]:若方括号内为一个值,则向下取整,否则为布尔判断

集合P:素数集合。

题目分析:

题目是一个积性函数。做法之一是洲阁筛,也可以采用Min_25筛。

对于一个可以进行Min_25筛法的积性函数,它需要满足与洲阁筛相同的条件,即:

对于$f(p), p \in P$,它可以多项式表出。对于$f(p^k),p \in P$可以被快速计算出。

这道题中$f(p) = p-1$再对$2$进行修正即可。

对于1的情况我们单独考虑,现在我们对答案进行一些变换。

$$\sum_{i=2}^{n}f(i) = \sum_{2<=p^e<=n, p \in P} f(p^e)(1+\sum_{2<=i<=[\frac{n}{p^e}],i质因子大于p}f(i)) = \sum_{2<=p<=\sqrt n,p^e<=n, p \in P} f(p^e)(1+\sum_{2<=i<=[\frac{n}{p^e}],i质因子大于p}f(i))+\sum _{p \in P,\sqrt n<p<=n}f(p)$$

我们注意到中间刺眼的中文,不妨以此为根据设置dp状态。

令$$g_{n,m}=\sum_{i=2,i的质因子大于m}^{n}f(i)$$

它的递推式不难写出来。根据上面那串式子:

$$g_{n,m}=\sum_{i=m,i \in P}^{\sqrt n}[p^e \leq n]([e \neq 1]+\sum_{i=p+1,i的质因子大于p}^{[\frac{n}{p^e}]}f(i))+\sum_{i=m+1,i \in P}^{n}f(i) = \sum_{i=m,i \in P}^{\sqrt n}[p^e \leq n]([e \neq 1]+g_{[\frac{n}{p^e}],p})+\sum_{i=m+1,i \in P}^{n}f(i)$$ 之后我们可以发现后面那一部分等于$m+1$到$n$的所有素数.

朱老大的论文似乎在这个式子上有一些问题,这个式子是我加了修正的,可以对比原式找到区别。

现在我们重点考虑后面的部分,质数前缀和的求解。 我们可以用DP模拟埃拉托斯特尼筛法来完成。现在对f(p)这个多项式的每个单项式分开考虑。

令$$h_{n,m}=\sum_{i=2,i为素数或i质因子大于m}f(i)$$

由埃氏筛可知$$h_{n,m}=h_{n,m-1}-p_m^s*(h_{[\frac{n}{p}],m-1}-h_{p_m,m-1})$$起始状态将所有数看做质数,做k次幂和。

由于n以下的合数至多的因子大小是$\sqrt n$,所以对于一个n只用筛前$\sqrt n$个素数。

g数组同理。

这样我们就完成整个过程了,现在我们来思考时间复杂度上的问题。这一部分我的证明存在争议,与论文上的有出入。希望有人可以帮助我确认出入之处。

先给出两个引理吧。

素数定理:$\pi(x) \approx \frac{x}{lnx} \approx li(x)$

数论分块:对于一个数n,它对1到n整除的结果只有$2\sqrt n$个,分别是1到$\sqrt n$与$n/\sqrt n$到$n/1$

首先是dp模拟埃氏筛。对于数论分块中的每一个数,每个小于它的根号的素数都被考虑,所以时间为,

$$O(\sum_{i=2}^{\sqrt n}\frac{\sqrt i}{lni})+O(\sum_{i=1}^{\sqrt n}\frac{\sqrt \frac{n}{i}}{ln{\frac{n}{i}}})$$

对于前面的大O,将$\sqrt i$放缩到$\sqrt n$,$lni$放缩到$lnn$,因为根号的增长远大于对数,所以放缩成立。前面被证明是$O(\frac{n^{0.75}}{lnn})$的。

后面的比较复杂,将它看做积分,即$$O(\int_1^{\sqrt n}\frac{\sqrt \frac{n}{x}}{ln\frac{n}{x}}dx)$$

由于对数函数增长极慢,不妨将分母用同样的放缩。当然也可以查积分表得到与我相同的结论。这样再对单项式函数做积分就简单了,得到$$O(\frac{\sqrt n}{lnn}*[2\sqrt x]_1^{\sqrt n})=O(\frac{n^{0.75}}{lnn})$$。

埃氏筛的复杂度得证,我们再来看看Min_25筛的表现。论文中通过证明得出一个与运行效率不相符的时间复杂度,我试着用其它方法得到它的复杂度。

观察Min_25的特点,它与DP埃氏筛的区别在于多枚举了质数的次幂。这样我们不妨对于质数的次幂分开考虑。

首先是质数本身,如果只枚举它,时间与埃氏筛DP相同。实际上它代表的是二次方,否则不被考虑。

然后是质数的平方,它要小于等于n。接着是质数的三次方,它也要小于等于n,然后是四次方,五次方。我们对第x次方小于等于n做一些转化使得他们统一。

$p^x \leq n \leftrightarrow p \leq n^{1/x} \leftrightarrow p^2 \leq n^{2/x}$

这时候我们的复杂度相当于对$n^{2/2},n^{2/3},n^{2/4}$做埃氏筛DP。每个的时间在上面分析了,所以下面直接转化成积分的形式。

$$O(\int_{2}^{log_{2}n}\frac{n^{\frac{3}{2x}}}{ln{n^{\frac{2}{x}}}}dx)$$

$$=O(\frac{1}{lnn}\int_{2}^{log_{2}n}\frac{n^{\frac{3}{2x}}}{\frac{2}{x}}dx)$$

$$=O(\frac{1}{2lnn}\int_{2}^{log_{2}n}{x*n^{\frac{3}{2x}}}dx)$$

$$=O(\frac{1}{2lnn}\int_{2}^{log_{2}n}{x*a^{\frac{1}{x}}}dx),a = n^{\frac{3}{2}}$$

接下俩数学好的可以换元,令$y=\frac{1}{x}$,再令$z = a^y$,求$$\int \frac{1}{ln^3{z}dz}$$即可。

现在跳过这些步骤,得到结论是

$$O([\frac{x(x+\ln a)a^\frac{1}{x}-\ln^2 a\operatorname{li}(a^{\frac{1}{x}})}{4lnn}]_{2}^{log_{2}n})$$

这个答案是负的,证明我可能某个步骤写错了。但是代入2可以得到时间是$O(n^{\frac{3}{4}})$,递归的过程不会重复计算。

继续写下去我也写不动了。到此打止。

代码:

 #include<bits/stdc++.h>
using namespace std; const int SQR = ;
const int mod = ; long long n; int prime[SQR],flag[SQR+],num;
long long h[SQR*+],sqr;
long long fh[SQR*+]; void getprime(int N){
for(int i=;i<=N;i++){
if(!flag[i]) prime[++num] = i;
for(int j=;j<=num&&i*prime[j] <= N;j++){
flag[i*prime[j]] = ;
if(i%prime[j] == ) break;
}
}
} void geth(int ft){
for(int i=;i<=num;i++){int zt = (ft > ?prime[i]:);
for(int j=;j<=sqr&&(1ll*prime[i]*prime[i]<=(n/j));j++){
long long nxt = 1ll*j*prime[i]; int plu = *sqr-j+;
if(nxt > sqr) h[plu] -= 1ll*zt*(h[n/nxt]-h[prime[i]-])%mod;
else h[plu] -= 1ll*zt*(h[*sqr-nxt+]-h[prime[i]-])%mod;
h[plu]<?h[plu]+=mod:;
}
for(int j=sqr;j>=&&(1ll*prime[i]*prime[i]<=j);j--){
h[j] -= 1ll*zt*(h[j/prime[i]]-h[prime[i]-])%mod;
h[j]<?h[j]+=mod:;
}
}
} int f(int now,int zt){
if(now <= sqr){
if(now <= || prime[zt] >= now) return ;
int ans = fh[now]-fh[prime[zt]]; if(ans < ) ans += mod;
if(1ll*prime[zt]*prime[zt] >= now) return ans;
for(int i=zt+;1ll*prime[i]*prime[i] <= now;i++){
long long dt = prime[i],k=;
while(dt <= now){
ans += ((prime[i]^k)*(f(now/dt,i)+))%mod; ans %= mod;
dt = dt*prime[i];k++;
}
ans-=(prime[i]^); if(ans < ) ans += mod;
}
return ans;
}else{
long long rd = n/(*sqr-now+);
int ans = fh[now]-fh[prime[zt]]; if(ans < ) ans += mod;
if(1ll*prime[zt]*prime[zt] >= rd) return ans;
for(int i=zt+;1ll*prime[i]*prime[i] <= rd&&i<=num;i++){
long long dt = prime[i],k=;
while(dt <= rd){
if(rd/dt <= sqr) ans += ((prime[i]^k)*(f(rd/dt,i)+))%mod;
else ans += ((prime[i]^k)*(f(*sqr-(*sqr-now+)*dt+,i)+))%mod;
ans %= mod; dt = dt*prime[i];k++;
}
ans-=(prime[i]^); if(ans < ) ans += mod;
}
return ans;
}
} void work(){
for(int i=;i<=sqr;i++){h[i] = (h[i-] + i)%mod;}
for(int i=;i<=sqr;i++){
long long fak=(n/i)%mod;h[sqr*-i+]=((+fak)*(fak-)/)%mod;
}
geth(); for(int i=;i<=*sqr;i++) fh[i] += h[i];
for(int i=;i<=sqr;i++) h[i] = i-; for(int i=;i<=sqr;i++) h[*sqr-i+]=(n/i-)%mod;
geth(); for(int i=;i<=*sqr;i++) fh[i] = fh[i]-h[i]+,fh[i] =(fh[i]+mod)%mod;
printf("%d",f(*sqr,)+);
} int main(){
scanf("%lld",&n); sqr = sqrt(n);
if(n == ){puts("");return ;}
getprime(sqr);work();
return ;
}

LOJ6053 简单的函数 【Min_25筛】【埃拉托斯特尼筛】的更多相关文章

  1. 洛谷P3383 【模板】线性筛素数 (埃拉托斯特尼筛法)

    题目描述 如题,给定一个范围N,你需要处理M个某数字是否为质数的询问(每个数字均在范围1-N内) 输入输出格式 输入格式: 第一行包含两个正整数N.M,分别表示查询的范围和查询的个数. 接下来M行每行 ...

  2. 利用OpenMP实现埃拉托斯特尼(Eratosthenes)素数筛法并行化 分类: 算法与数据结构 2015-05-09 12:24 157人阅读 评论(0) 收藏

    1.算法简介 1.1筛法起源 筛法是一种简单检定素数的算法.据说是古希腊的埃拉托斯特尼(Eratosthenes,约公元前274-194年)发明的,又称埃拉托斯特尼筛法(sieve of Eratos ...

  3. 统计所有小于非负整数 n 的质数的数量,埃拉托斯特尼筛法

    素数的定义:质数又称素数.一个大于1的自然数,除了1和它自身外,不能被其他自然数整除的数叫做质数. 1.暴力算法: 令i=2; 当i<n的时候,我们循环找出2-i的质数,即让i%(2~i-1), ...

  4. LeetCode - 204. Count Primes - 埃拉托斯特尼筛法 95.12% - (C++) - Sieve of Eratosthenes

    原题 原题链接 Description: Count the number of prime numbers less than a non-negative number, n. 计算小于非负数n的 ...

  5. LOJ6053 简单的函数(min_25筛)

    题目链接:LOJ 题目大意:从前有个积性函数 $f$ 满足 $f(1)=1,f(p^k)=p\oplus k$.(异或)求其前 $n$ 项的和对 $10^9+7$ 取模的值. $1\le n\le 1 ...

  6. [LOJ6053]简单的函数:Min_25筛

    分析 因为题目中所给函数\(f(x)\)的前缀和无法较快得出,考虑打表以下两个函数: \[ g(x)=x \times [x是质数] \] \[ h(x)=1 \times [x是质数] \] 这两个 ...

  7. LOJ.6053.简单的函数(Min_25筛)

    题目链接 Min_25筛见这里: https://www.cnblogs.com/cjyyb/p/9185093.html https://www.cnblogs.com/zhoushuyu/p/91 ...

  8. LOJ 6053 简单的函数——min_25筛

    题目:https://loj.ac/problem/6053 min_25筛:https://www.cnblogs.com/cjyyb/p/9185093.html 这里把计算 s( n , j ) ...

  9. 简单的函数——Min_25筛

    %%yyb %%zsy 就是实现一下Min-25筛 筛积性函数的操作 首先要得到 $G(M,j)=\sum_{t=j}^{cnt} \sum_{e=1}^{p_t^{e+1}<=M} [\phi ...

随机推荐

  1. 初步学习Xamarin的感受

    一直仰慕Xamarin的大名,最近抽空去浅学了一下. 最后有一种这东西不咋地,又有一种这东西还不错的感觉 先说下为什么不咋地? 如果在公司项目使用Xamarin.forms这个东西.按照国内APP设计 ...

  2. ASP.NET Core 企业开发架构概述

    企业开发框架包括垂直方向架构和水平方向架构.垂直方向架构是指一个应用程序的由下到上叠加多层的架构,同时这样的程序又叫整体式程序.水平方向架构是指将大应用分成若干小的应用实现系统功能的架构,同时这样的系 ...

  3. ajax成功后XML 解析错误:格式不佳

    就是Ajax发送请求后,意图回显数据时会出现这个错误,貌似chrome浏览器不会报用火狐能看到: 可能的原因有两个,就是后台应该返回一个json格式的字符串,但是你返回的是浏览器看不懂的,也就是返回格 ...

  4. 监控系统对比 Ganglia vs Open-falcon vs Prometheus vs Zabbix vs Nagios vs PandoraFMS

    Zabbix vs Nagios vs PandoraFMS: an in depth comparison - Pandora FMS - The Monitoring Bloghttps://bl ...

  5. asp.net Json序列化

    Json作为一种数据传输格式与标准被广泛的使用在项目开发中,可以说简直离不开它.那么怎么来生成JSON格式的数据就成了我们首先需要解决的问题这里我们使用.net. 首先是获取数据 public ban ...

  6. Mixing x86 with x64 code (混合编写x86和x64代码)

    几个月前我小小的研究了在WOW64下的32位进程中运行native x64代码. 第二个设想是在64位进程下运行x86代码.它们都是可以的,如我google的一样, 已经有人在使用这两种方法了: ht ...

  7. for循环游标

  8. AngularJS:directive自定义的指令

    除了 AngularJS 内置的指令外,我们还可以创建自定义指令. 你可以使用 .directive 函数来添加自定义的指令. 要调用自定义指令,HTML 元素上需要添加自定义指令名. 使用驼峰法来命 ...

  9. windows浏览器访问虚拟机开的rabbitmq服务,无法访问

    根据这个博主的建议 https://blog.csdn.net/csdnliuxin123524/article/details/78207427 换了一个浏览器上火狐浏览器输入“localhost: ...

  10. Centos6.8 安装git

    1.下载安装包 wget https://mirrors.edge.kernel.org/pub/software/scm/git/git-2.8.0.tar.gz 2.安装依赖 sudo yum - ...