一个简单的问题:求 (i为质数)
设小于的质数有t个,其中表示第i个质数
再设 (i为质数或者i的最小质因子不小于)
那么有
其中 , 就是答案
因为每次S(x, y)都是由S(?, y-1)转移过来,而有效的"?"只有个,所以总体复杂度小于O(n)
第二个问题:已知F(x)是积性函数,且当p为质数时 ,求
积性函数很重要的性质(引用)先写在前面:
仍然考虑求 (i的最小质因子不小于)
那么答案就是
考虑用上图中的性质①来求
首先把所有满足p为质数且的全部加上
得到:(第一部分)
之后再将所有剩下的F()加上,也就是把所有满足x质因子不止一个的F(x)加上
得到: (第二部分)搞定!
这个可以用递归来实现,复杂度约为O(),c为一个满足1>c>0.25的常数
第三个问题:LibreOJ: 6053. 简单的函数
这道题和第二道题的唯一区别就是当p为质数时,值不同
这样子的话,对于,第二部分算法并没有变,变的是第一部分算法
→仔细分析一下,当p为不为2的质数的时候,
→所以只需要在第一部分算法后面多减掉质数的个数即可!其中p为2的时候要特判,因为此时F(2) = 3
具体看程序
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<map>
#include<string>
#include<math.h>
#include<queue>
#include<stack>
#include<iostream>
using namespace std;
#define LL long long
#define mod 1000000007
#define er 500000004
int cnt, s[200005], S[200005], id[200005], B, m, h[200005];
bool flag[200005];
LL n, w[200005], pri[200005];
void Primeset(int n)
{
int i, j;
for(i=2;i<=n;i++)
{
if(flag[i]==0)
{
pri[++cnt] = i;
s[cnt] = (s[cnt-1]+i)%mod;
}
for(j=1;j<=cnt&&i*pri[j]<=n;j++)
{
flag[i*pri[j]] = 1;
if(i%pri[j]==0)
break;
}
}
}
//S_f(n,y)=S(n,p_t)-\sum_{i=1}^{y-1}p_i+\sum_{i=y}^t\sum_{e=2}^{p^e\leqslant n}F(p_i^e)
LL F(LL x, int y)
{
LL t1;
int i, k, e, ans;
if(x<=1 || pri[y]>x)
return 0;
if(x>B)
k = n/x;
if(x<=B)
k = id[x];
//找到k满足w[k]=x
ans = (S[k]-s[y-1]-(h[k]-(y-1)))%mod;
if(y==1)
ans += 2;
for(i=y;i<=cnt&&(LL)pri[i]*pri[i]<=x;i++)
{
t1 = pri[i];
for(e=1;t1*pri[i]<=x;e++)
{
ans = (ans+(F(x/t1, i+1)*(pri[i]^e)%mod+(pri[i]^(e+1)))%mod)%mod;
t1 *= pri[i];
}
}
return ans;
}
int main(void)
{
LL i, j, k, last;
scanf("%lld", &n);
B = sqrt(n), Primeset(B);
for(i=1;i<=n;i=last+1) //初始化
{
w[++m] = n/i;
h[m] = (w[m]-1)%mod;
S[m] = (1+w[m])%mod*(w[m]%mod)%mod*er%mod-1;
last = n/(n/i);
if(n/i<=B)
id[n/i] = m;
}
//id[i]:哪个x满足w[x]等于n/w[i]
for(j=1;j<=cnt;j++)
{
for(i=1;i<=m&&pri[j]*pri[j]<=w[i];i++)
{
if(w[i]/pri[j]<=B)
k = id[w[i]/pri[j]];
else
k = n/(w[i]/pri[j]);
S[i] = (S[i]-(LL)pri[j]*(S[k]-s[j-1])%mod+mod)%mod;
h[i] = (h[i]-(h[k]-(j-1)))%mod;
}
}
//S[i]:小于等于w[i]所有质数的和
//h[i]:小于等于w[i]有多少个质数
printf("%lld\n", (F(n, 1)+1+mod)%mod);
return 0;
}