链接
https://odzkskevi.qnssl.com/b8a010f2f416b854e654ac56ba327f67?v=1537778253
题解
设
c
p
(
x
)
cp(x)
cp(x)为
x
x
x的素约数个数,
m
a
r
k
(
x
)
mark(x)
mark(x),为不大于
x
x
x的素数个数,
e
(
x
)
e(x)
e(x)为我要求的期望
那么
e
(
x
)
=
(
1
c
p
(
x
)
∑
i
∈
p
r
i
m
e
,
i
∣
x
e
(
i
)
)
+
m
a
r
k
(
x
)
c
p
(
x
)
e(x)=\left(\frac{1}{cp(x)}\sum_{i\in prime,i|x}e(i)\right)+\frac{mark(x)}{cp(x)}
e(x)=⎝⎛cp(x)1i∈prime,i∣x∑e(i)⎠⎞+cp(x)mark(x)
直接枚举
i
i
i,然后再枚举素数
p
r
i
m
e
(
j
)
prime(j)
prime(j),用
e
(
i
)
e(i)
e(i)去更新
e
(
i
×
p
r
i
m
e
(
j
)
)
e(i\times prime(j))
e(i×prime(j))即可
复杂度小于
O
(
n
log
2
n
)
O(n\log_2n)
O(nlog2n)
代码
//概率
#include <bits/stdc++.h>
#define maxn 1000010
using namespace std;
int mark[maxn], cp[maxn], prime[maxn];
double f[maxn];
void preprocess()
{
int i, j;
for(i=2;i<maxn;i++)
{
if(!mark[i])prime[++*prime]=i, cp[i]=1;
for(j=1;j<=*prime and i*prime[j]<maxn;j++)
{
mark[i*prime[j]]=1;
if(i%prime[j]==0)
{
cp[i*prime[j]]=cp[i];
break;
}
else cp[i*prime[j]]=cp[i]+1;
}
}
for(i=2,mark[1]=1;i<maxn;i++)mark[i]+=mark[i-1];
for(i=1;i<maxn;i++)mark[i]=i-mark[i];
for(i=2;i<maxn;i++)
{
f[i]+=1.0*mark[i]/cp[i];
for(j=1;j<=*prime and i*prime[j]<maxn;j++)f[i*prime[j]]+=f[i]/cp[i*prime[j]];
}
}
int main()
{
int T, kase=0, x;
preprocess();
scanf("%d",&T);
while(T--)
{
scanf("%d",&x);
printf("Case %d: %.10lf\n",++kase,f[x]);
}
return 0;
}