标签:Function lfloor frac int Sum rfloor Another sum mod
对原式反演,问题即求$\sum_{d=1}^{n}\mu(d)\left(\sum_{i=1}^{\lfloor\frac{n}{d}\rfloor}H(id)\right)^{2}$
设置阈值$B$,并对$d$和$B$的大小关系分类讨论——
第一部分
对于$d\le B$,记$F_{1}(m,t)=\sum_{i=1}^{m}H(it)$,则原式即$\sum_{d=1}^{B}\mu(d)F_{1}^{2}(\lfloor\frac{n}{d}\rfloor,d)$
关于$F_{1}(m,t)$,代入$H(it)=\frac{H(i)H(t)}{H(\gcd(i,t))}$,并枚举$d=\gcd(i,t)$后反演,即
$$
F_{1}(m,t)=H(t)\sum_{d\mid t}\frac{1}{H(d)}\sum_{g\mid \frac{t}{d}}\mu(g)F_{1}(\lfloor\frac{m}{dg}\rfloor,dg)=H(t)\sum_{T\mid t}\left(\sum_{d\mid T}\frac{\mu(\frac{T}{d})}{H(d)}\right)F_{1}(\lfloor\frac{m}{T}\rfloor,T)
$$
记中间项为$H'(T)$(即$\mu *\frac{1}{H}$),可以$o(B\log n)$预处理出
枚举$d$并记忆化搜索$F_{1}(\lfloor\frac{n}{d}\rfloor,d)$,边界条件为$m=0$或$t=1$,后者用${\rm Min}25$筛$o(\frac{n^{\frac{3}{4}}}{\log n})$预处理出
关于复杂度,将其按初始状态和转移状态分类讨论:
1.关于初始状态,状态数为$o(B)$,转移数为$\sum_{d=1}^{B}\sigma(d)=o(B\log n)$
2.关于转移状态,均形如$(\lfloor\frac{n}{d^{2}x}\rfloor,d)$(其中$d\le B$),状态数为$\sum_{d=1}^{B}\frac{\sqrt{n}}{d}=o(\sqrt{n}\log n)$,转移数为
$$
\sum_{d=1}^{B}\frac{\sqrt{n}\sigma(d)}{d}=\sqrt{n}\sum_{i=1}^{B}\frac{1}{i}\sum_{d=1}^{\lfloor\frac{B}{i}\rfloor}\frac{1}{d}=\sqrt{n}\log^{2}n
$$
第二部分
对于$d>B$,记$F_{2}(m,i,j)=\sum_{d=1}^{m}\mu(d)H(id)H(jd)$,则原式即
$$
\sum_{i=1}^{\lfloor\frac{n}{B}\rfloor}\sum_{j=1}^{\lfloor\frac{n}{B}\rfloor}\left(F_{2}(\lfloor\frac{n}{\max(i,j)}\rfloor,i,j)-F_{2}(B,i,j)\right)
$$
关于$F_{2}(m,i,j)$,类似$F_{1}$的处理方式,即
$$
F_{2}(m,i,j)=H(i)H(j)\sum_{T_{1}\mid i}H'(T_{1})\sum_{T_{2}\mid i}H'(T_{2})\sum_{d=1}^{\lfloor\frac{m}{T}\rfloor}\mu(dT)H^{2}(dT)
$$
(其中$T={\rm lcm}(T_{1},T_{2})$)
记最后一项为$G(\lfloor\frac{m}{T}\rfloor,T)$,注意到$\mu(dT)\ne 0\Longrightarrow \gcd(d,T)=1$,即
$$
G(m,t)=\mu(t)H^{2}(t)\sum_{g\mid t}\mu(g)G(\lfloor\frac{m}{g}\rfloor,g)
$$
枚举$i,j,T_{1}$和$T_{2}$并记忆化搜索$G(\lfloor\frac{m}{T}\rfloor,T)$,边界的处理与$F_{1}$相同
关于复杂度,同样按初始状态和转移状态分类,后者的分析也与$F_{1}$相同
关于初始状态,不妨将$\max(i,j)$改为$i$,状态数为$\sum_{T_{1}=1}^{\lfloor\frac{n}{B}\rfloor}\sum_{T_{2}=1}^{\lfloor\frac{n}{B}\rfloor}\sqrt{\frac{n}{T_{1}^{2}T_{2}}}=\frac{n\log n}{\sqrt{B}}$,转移数为
$$
\sum_{T_{1}=1}^{\lfloor\frac{n}{B}\rfloor}\sum_{T_{2}=1}^{\lfloor\frac{n}{B}\rfloor}\sqrt{\frac{n}{T_{1}^{2}T_{2}}}\sigma(T_{1})\sigma(T_{2})=
\sqrt{n}\sum_{d_{1}=1}^{\lfloor\frac{n}{B}\rfloor}\frac{1}{d_{1}}\sum_{d_{2}=1}^{\lfloor\frac{n}{B}\rfloor}\frac{1}{\sqrt{d_{2}}}\sum_{T_{1}=1}^{\lfloor\frac{n}{Bd_{1}}\rfloor}\frac{1}{T_{1}}\sum_{T_{2}=1}^{\lfloor\frac{n}{Bd_{2}}\rfloor}\frac{1}{\sqrt{T_{2}}}=\frac{n\log^{3}n}{\sqrt{B}}
$$
取$B=n^{\frac{2}{3}}$,时间复杂度为$o(\frac{n^{\frac{3}{4}}}{\log n}+n^{\frac{2}{3}}\log^{3}n)$,空间复杂度为$o(n^{\frac{2}{3}}\log n)$
两者均略卡常,考虑以下两个优化:
1.仅搜索$F_{1}$和$G$的(第二维$t$)满足$\mu(t)\ne 0$的状态
2.在预处理约数时,仅考虑满足$\mu(t)\ne 0$的$t$的约数(前者优化后$G$的状态数仅$10^{6}$)
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 1100000 4 #define mod 1000000007 5 #define ll long long 6 int n,t,K,B,ans,vis[N],p[N],mu[N],H[N],iH[N],HH[N],val[N],S[N],f1[N],g[N]; 7 ll P[N];vector<int>fac[N];unordered_map<int,int>F1[N],G[N]; 8 int sqr(int n){ 9 return (ll)n*n%mod; 10 } 11 void add(int &x,int y){ 12 x+=y;if (x>=mod)x-=mod; 13 } 14 int qpow(int n,int m){ 15 int s=n,ans=1; 16 while (m){ 17 if (m&1)ans=(ll)ans*s%mod; 18 s=sqr(s),m>>=1; 19 } 20 return ans; 21 } 22 int get_S1(int n){ 23 return (ll)n*(n+1)/2%mod; 24 } 25 int get_S2(int n){ 26 return (ll)n*(n+1)%mod*((n<<1)+1)%mod*(mod+1)/6%mod; 27 } 28 int get_id(int m){ 29 return (m<=K ? m : (K<<1)-n/m+1); 30 } 31 void get_f1(){ 32 for(int i=1;i<=(K<<1);i++)S[i]=(get_S1(val[i])-1+mod)%mod; 33 for(int i=1;p[i]<=K;i++) 34 for(int j=(K<<1);(j)&&(P[i]<=val[j]);j--) 35 S[j]=(S[j]-(ll)p[i]*(S[get_id(val[j]/p[i])]-S[p[i]-1]+mod)%mod+mod)%mod; 36 for(int i=1;i<=(K<<1);i++)f1[i]=(S[i]-S[get_id((int)sqrt(val[i]))]+mod)%mod; 37 for(int i=p[0];i;i--) 38 for(int j=(K<<1);(j)&&(P[i]<=val[j]);j--){ 39 ll s=p[i]; 40 for(int e=1;s*p[i]<=val[j];e++,s*=p[i]){ 41 int jj=get_id(val[j]/s); 42 f1[j]=(f1[j]+(ll)p[i]*((val[j]/s<P[i] ? (S[jj]-S[p[i]]+mod) : f1[jj])+1))%mod; 43 } 44 f1[j]=(f1[j]+p[i])%mod; 45 } 46 for(int i=1;i<=(K<<1);i++)f1[i]=(f1[i]+1)%mod; 47 } 48 void get_g(){ 49 for(int i=1;i<=(K<<1);i++)S[i]=(get_S2(val[i])-1+mod)%mod; 50 for(int i=1;p[i]<=K;i++) 51 for(int j=(K<<1);(j)&&(P[i]<=val[j]);j--) 52 S[j]=(S[j]-(ll)sqr(p[i])*(S[get_id(val[j]/p[i])]-S[p[i]-1]+mod)%mod+mod)%mod; 53 for(int i=1;i<=(K<<1);i++)S[i]=(mod-S[i])%mod; 54 for(int i=1;i<=(K<<1);i++)g[i]=(S[i]-S[get_id((int)sqrt(val[i]))]+mod)%mod; 55 for(int i=p[0];i;i--) 56 for(int j=(K<<1);(j)&&(P[i]<=val[j]);j--){ 57 int jj=get_id(val[j]/p[i]); 58 g[j]=(g[j]+(ll)(mod-sqr(p[i]))*((val[j]/p[i]<P[i] ? (S[jj]-S[p[i]]+mod) : g[jj])+1))%mod; 59 } 60 for(int i=1;i<=(K<<1);i++)g[i]=(g[i]+1)%mod; 61 } 62 int get_F1(int m,int t){ 63 if (!m)return 0; 64 if (t==1)return f1[get_id(m)]; 65 if (F1[t].find(m)!=F1[t].end())return F1[t][m]; 66 int ans=0; 67 for(int i:fac[t])ans=(ans+(ll)HH[i]*get_F1(m/i,i))%mod; 68 ans=(ll)ans*H[t]%mod; 69 return F1[t][m]=ans; 70 } 71 int get_G(int m,int t){ 72 if (!m)return 0; 73 if (t==1)return g[get_id(m)]; 74 if (G[t].find(m)!=G[t].end())return G[t][m]; 75 int ans=0; 76 for(int i:fac[t]){ 77 int s=get_G(m/i,i); 78 ans=(ans+(mu[i]>0 ? s : mod-s))%mod; 79 } 80 ans=(ll)ans*sqr(H[t])%mod; 81 if (mu[t]<0)ans=(mod-ans)%mod; 82 return G[t][m]=ans; 83 } 84 int main(){ 85 mu[1]=H[1]=iH[1]=1; 86 for(int i=2;i<N;i++){ 87 if (!vis[i]){ 88 p[++p[0]]=i,P[p[0]]=(ll)i*i,mu[i]=-1; 89 H[i]=i,iH[i]=qpow(i,mod-2); 90 } 91 for(int j=1;(j<=p[0])&&(i*p[j]<N);j++){ 92 vis[i*p[j]]=1; 93 if (i%p[j]){ 94 mu[i*p[j]]=-mu[i]; 95 H[i*p[j]]=H[i]*p[j],iH[i*p[j]]=(ll)iH[i]*iH[p[j]]%mod; 96 } 97 else{ 98 mu[i*p[j]]=0; 99 H[i*p[j]]=H[i],iH[i*p[j]]=iH[i]; 100 break; 101 } 102 } 103 } 104 for(int i=1;i<N;i++) 105 for(int j=i;j<N;j+=i){ 106 if (mu[j])fac[j].push_back(i); 107 if (mu[j/i])HH[j]=(HH[j]+(mu[j/i]>0 ? iH[i] : mod-iH[i]))%mod; 108 } 109 scanf("%d",&t); 110 while (t--){ 111 scanf("%d",&n); 112 K=(int)sqrt(n),B=n/(int)pow(n,1.0/3),ans=0; 113 for(int i=1;i<=K;i++)val[i]=i,val[i+K]=n/(K-i+1); 114 get_f1(),get_g(); 115 for(int i=1;i<=B;i++) 116 if (mu[i]){ 117 int s=sqr(get_F1(n/i,i)); 118 ans=(ans+(mu[i]>0 ? s : mod-s))%mod; 119 } 120 int n0=n/B; 121 for(int T1=1;T1<=n0;T1++) 122 for(int T2=1;T2<=n0;T2++){ 123 int T=T1*T2/__gcd(T1,T2); 124 if (!mu[T])continue; 125 for(int i=T1;i<=n0;i+=T1) 126 for(int j=T2;j<=n0;j+=T2) 127 ans=(ans+(ll)H[i]*H[j]%mod*HH[T1]%mod*HH[T2]%mod*(get_G(n/max(i,j)/T,T)-get_G(B/T,T)+mod))%mod; 128 } 129 printf("%d\n",ans); 130 } 131 return 0; 132 }View Code
标签:Function,lfloor,frac,int,Sum,rfloor,Another,sum,mod 来源: https://www.cnblogs.com/PYWBKTDA/p/16563149.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。