P3768-简单的数学题【莫比乌斯反演,杜教筛】
正題
題目鏈接:https://www.luogu.com.cn/problem/P3768
題目大意
給出n,pn,pn,p求∑i=1n∑j=1ngcd(i,j)?i?j\sum_{i=1}^n\sum_{j=1}^ngcd(i,j)*i*ji=1∑n?j=1∑n?gcd(i,j)?i?j模ppp的值。
解題思路
下文中定義Hy(x)=∑i=1xiyH_y(x)=\sum_{i=1}^xi^yHy?(x)=∑i=1x?iy
首先顯然是上莫反推式子f(x)=∑i=1n∑j=1n[gcd(i,j)==x]?i?j=x2∑i=1?nx?∑j=1?nx?ij[gcd(i,j)==1]f(x)=\sum_{i=1}^n\sum_{j=1}^n[gcd(i,j)==x]*i*j=x^2\sum_{i=1}^{\lfloor\frac{n}{x}\rfloor}\sum_{j=1}^{\lfloor\frac{n}{x}\rfloor}ij[gcd(i,j)==1]f(x)=i=1∑n?j=1∑n?[gcd(i,j)==x]?i?j=x2i=1∑?xn???j=1∑?xn???ij[gcd(i,j)==1]
F(x)=∑x∣df(d)=x2∑i=1?nx?∑j=1?nx?ij=x2H1(?nx?)2F(x)=\sum_{x|d}f(d)=x^2\sum_{i=1}^{\lfloor\frac{n}{x}\rfloor}\sum_{j=1}^{\lfloor\frac{n}{x}\rfloor}ij=x^2H_1(\lfloor\frac{n}{x}\rfloor)^2F(x)=x∣d∑?f(d)=x2i=1∑?xn???j=1∑?xn???ij=x2H1?(?xn??)2
然后答案為∑x=1nf(x)=∑x=1nx2∑x∣dF(d)μ(xd)=∑d=1nF(d)∑x∣dμ(xd)x2\sum_{x=1}^nf(x)=\sum_{x=1}^nx^2\sum_{x|d}F(d)\mu(\frac{x}ze8trgl8bvbq)=\sum_{d=1}^nF(d)\sum_{x|d}\mu(\frac{x}ze8trgl8bvbq)x^2x=1∑n?f(x)=x=1∑n?x2x∣d∑?F(d)μ(dx?)=d=1∑n?F(d)x∣d∑?μ(dx?)x2
展開F(x)F(x)F(x)有
∑d=1nH1(?nd?)2d2∑x∣dμ(xd)x2\sum_{d=1}^nH_1(\lfloor\frac{n}ze8trgl8bvbq\rfloor)^2d^2\sum_{x|d}\mu(\frac{x}ze8trgl8bvbq)x^2d=1∑n?H1?(?dn??)2d2x∣d∑?μ(dx?)x2
前面可以整除分塊,問題變為了如何求d2∑x∣dμ(xd)x2d^2\sum_{x|d}\mu(\frac{x}ze8trgl8bvbq)x^2d2∑x∣d?μ(dx?)x2的前綴和
因為nnn很大,所以我們考慮使用杜教篩。
先考慮一個式子μ?I=??μ?I?φ=??φ?μ?id=φ\mu*I=\epsilon\ \ \ \Rightarrow\ \ \ \mu*I*\varphi=\epsilon *\varphi\ \ \ \Rightarrow\ \ \ \mu*id=\varphiμ?I=????????μ?I?φ=??φ???????μ?id=φ
所以上面那個東西就可以變成∑d=1nH1(?nd?)2d2φ(d)\sum_{d=1}^nH_1(\lfloor\frac{n}ze8trgl8bvbq\rfloor)^2d^2\varphi(d)d=1∑n?H1?(?dn??)2d2φ(d)
上杜教篩f(n)=φ(n)n2,g(n)=n2f(n)=\varphi(n)n^2,g(n)=n^2f(n)=φ(n)n2,g(n)=n2,f(n)g(n)=∑d∣nf(d)g(nd)=∑d∣nφ(d)d2?n2d2=n2∑d∣nφ(d)=n3f(n)g(n)=\sum_{d|n}f(d)g(\frac{n}ze8trgl8bvbq)=\sum_{d|n}\varphi(d)d^2*\frac{n^2}{d^2}=n^2\sum_{d|n}\varphi(d)=n^3f(n)g(n)=d∣n∑?f(d)g(dn?)=d∣n∑?φ(d)d2?d2n2?=n2d∣n∑?φ(d)=n3
然后有結論H3(n)=H1(n)2H_3(n)=H_1(n)^2H3?(n)=H1?(n)2,具體證明就用數學歸納法把,大致是多了一個n+1n+1n+1之后前者會多一個(n+1)3(n+1)^3(n+1)3,后者會多一個2?H1(n)?(n+1)+(n+1)2=(n+1)32*H_1(n)*(n+1)+(n+1)^2=(n+1)^32?H1?(n)?(n+1)+(n+1)2=(n+1)3。這樣就可以O(n23)O(n^\frac{2}{3})O(n32?)的篩我們需要的東西了。
然后就是套莫反了,值得一提的是H2(n)=n?(n+1)?(2n+1)6H_2(n)=\frac{n*(n+1)*(2n+1)}{6}H2?(n)=6n?(n+1)?(2n+1)?,大體上也是數學歸納法證明吧。
理論上時間復雜度應該是O(n23n)O(n^\frac{2}{3}\sqrt n)O(n32?n?)的,但是因為杜教篩的記憶化還有各種原因所以實際上其實跑的快很多了。
codecodecode
#include<cstdio> #include<cstring> #include<algorithm> #include<map> #define ll long long using namespace std; const ll N=8e6; ll n,p,cnt,inv2,inv6; ll phi[N],pri[N];bool v[N]; map<ll,ll> mark; void Prime(){phi[1]=1;for(ll i=2;i<N;i++){if(!v[i])pri[++cnt]=i,phi[i]=i-1;for(ll j=1;j<=cnt&&i*pri[j]<N;j++){v[i*pri[j]]=1;if(i%pri[j]==0){phi[i*pri[j]]=phi[i]*pri[j];break;}phi[i*pri[j]]=phi[i]*(pri[j]-1);}}for(ll i=1;i<N;i++)phi[i]=(phi[i-1]+phi[i]%p*i%p*i%p)%p;return; } ll power(ll x,ll b){ll ans=1;while(b){if(b&1)ans=ans*x%p;x=x*x%p;b>>=1;}return ans; } ll s1(ll x) {x%=p;return x*(x+1)%p*inv2%p;} ll s2(ll x) {x%=p;return x*(x+1)%p*(x+x+1)%p*inv6%p;} ll Sum(ll x){if(x<N)return phi[x];if(mark[x])return mark[x];ll ans=s1(x);ans=ans*ans%p;for(ll l=2,r;l<=x;l=r+1){r=x/(x/l);(ans-=(s2(r)-s2(l-1))*Sum(x/l)%p)%=p;}return mark[x]=(ans+p)%p; } int main() {scanf("%lld%lld",&p,&n);inv2=power(2,p-2);inv6=power(6,p-2);Prime();ll ans=0;for(ll l=1,r;l<=n;l=r+1){r=n/(n/l);ll tmp=s1(n/l);tmp=tmp*tmp%p;(ans+=(Sum(r)-Sum(l-1)+p)%p*tmp%p)%=p;}printf("%lld\n",ans); }總結
以上是生活随笔為你收集整理的P3768-简单的数学题【莫比乌斯反演,杜教筛】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 打电话怎么变声?手机通话变声器软件
- 下一篇: CF932E-Team Work【斯特林