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; }
四月櫻花