LG P6788 「EZEC-3」四月樱花
Description
在樱花盛开的四月,Muxii 望着满天飘落的樱花,向身旁的 ZZH 问道:
“究竟有多少朵樱花在这个四月飘落?”
ZZH 答道:“樱花飘落的朵数 $s$与时间 $t$ 有如下关系:
$s=\prod_{x=1}^t \prod_{y|x} \frac{y^{d(y)}}{\prod_{z|y}(z+1)^2}$
其中 $d(y)$ 表示 $y$ 的约数个数。”
但作为一个文科生萌新,Muxii 显然无法清楚地知道具体的数目,因此他只好继续向 ZZH 询问这个问题的答案。
由于数量可能很大,所以你只需要替 ZZH 告诉 Muxii 他所需要的答案对 $p$ 取模的结果就好了。
Solution
题中所求为
$$ans=\left(\prod_{x=1}^n\prod_{y|x}\frac{y^{d(y)}}{\prod_{z|y}(z+1)^2}\right)\bmod p$$
大力操作式子:因为
$$y^{d(y)}=\prod_{z|y}y=\prod_{z|y}z\cdot\frac{y}{z}=\prod_{z|y}z^2$$
和
$$\sum_{z|y,y|n}=d(\frac{n}{z})$$
所以
$$s=\prod_{x=1}^n\prod_{y|x}\frac{y^{d(y)}}{\prod_{z|y}(z+1)^2}=\prod_{x=1}^n\prod_{y|x}\prod_{z|y}\left(\frac{z}{z+1}\right)^2=\prod_{z=1}^n\left(\frac{z}{z+1}\right)^{2sumd(\lfloor\frac{n}{z}\rfloor)}$$
其中$sumd(n)=\sum_{i=1}^n d(i)$
由于要求$d$的前缀和,所以有杜教筛
设$f=d=1*1,g=\mu$,则$f*g=1*1*\mu=1$,可以使用杜教筛,现在需要求出$\mu$的前缀和
再次使用杜教筛即可
求原式的值可以用整除分块做
时间复杂度$\Theta(n^{\frac 23}+\sqrt{n}\log n)$


#include<iostream> #include<cstdio> using namespace std; long long n,mod,pmod,prime[6000005],mu[6000005],minn[6000005],d[6000005],tot,summu[605],sumd[605],ans=1; bool isprime[6000005],vst[600]; inline long long read() { long long w=0,f=1; char ch=0; while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); } while(ch>='0'&&ch<='9') { w=(w<<1)+(w<<3)+ch-'0'; ch=getchar(); } return w*f; } long long Mu(long long x) { return x<=5000000?mu[x]:summu[n/x]; } long long D(long long x) { return x<=5000000?d[x]:sumd[n/x]; } void djs(long long N) { if(N<=5000000||vst[n/N]) { return; } vst[n/N]=true; for(long long l=2;l<=N;) { long long r=N/(N/l); djs(N/l); (summu[n/N]+=(pmod-(r-l+1)*Mu(N/l)%pmod)%pmod)%=pmod; l=r+1; } (summu[n/N]+=1)%=pmod; for(long long l=2;l<=N;) { long long r=N/(N/l); (sumd[n/N]+=pmod-((Mu(r)-Mu(l-1)+pmod)%pmod)*D(N/l)%pmod)%=pmod; l=r+1; } (sumd[n/N]+=N)%=pmod; } long long ksm(long long a,long long p) { long long ret=1; while(p) { if(p&1) { (ret*=a)%=mod; } (a*=a)%=mod; p>>=1; } return ret; } int main() { n=read(); mod=read(); pmod=mod-1; mu[1]=d[1]=1; for(long long i=2;i<=5000000;i++) { if(!isprime[i]) { prime[++tot]=i; mu[i]=-1; d[i]=2; minn[i]=1; } for(long long j=1;j<=tot&&i*prime[j]<=5000000;j++) { isprime[i*prime[j]]=true; if(!(i%prime[j])) { minn[i*prime[j]]=minn[i]+1; d[i*prime[j]]=d[i]/(minn[i]+1)*(minn[i*prime[j]]+1); mu[i*prime[j]]=0; break; } minn[i*prime[j]]=1; d[i*prime[j]]=d[i]*d[prime[j]]; mu[i*prime[j]]=mu[i]*-1; } } for(long long i=2;i<=5000000;i++) { (d[i]+=d[i-1])%=pmod; ((mu[i]+=mu[i-1])+=pmod)%=pmod; } djs(n); for(long long l=1;l<=n;) { long long r=n/(n/l); (ans*=ksm(l*ksm(r+1,mod-2)%mod,D(n/l)))%=mod; l=r+1; } (ans*=ans)%=mod; printf("%lld\n",ans); return 0; }
四月樱花