日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[Spoj]Counting Divisors (cube)

發布時間:2024/9/5 编程问答 47 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [Spoj]Counting Divisors (cube) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

來自FallDream的博客,未經允許,請勿轉載,謝謝。


?

設d(x)表示x的約數個數,求$\sum_{i=1}^{n}d(i^{3})$

?? ? There are 5 Input files.? ?

? ? - Input #1: 1≤N≤10000, TL = 1s.

? ? - Input #2: 1≤T≤300, 1≤N≤10^8, TL = 20s.

? ? - Input #3: 1≤T≤75, 1≤N≤10^9, TL = 20s.

? ? - Input #4: 1≤T≤15, 1≤N≤10^10, TL = 20s.

? ? - Input #5: 1≤T≤2, 1≤N≤10^11, TL = 20s.

? ??

$i^{3}$的約數個數$d(i^{3})$是一個積性函數,所以轉而求$d(x)=\prod{F(pi^{ci})}$,其中$F ( pk ^ {ck} )=3ck+1$

可以直接洲閣篩 學了一天大概懂了 順便抄了個模板

-----

gi表示1-i中與前j個質數互質的數字的F之和

fi表示1-i中由小于根號n的后j個質數組成的數字的F之和

容易得出轉移方程 $$g[i][j]=g[i][j]-F(pk)g[\frac{i}{pk}][j-1]$$

$$ f[i][j]=f[i][j-1]+\sum_{ck>=1}F(pk^{ck})f[\frac{i}{pk^{ck}}][j]$$

顯然i只有根號種取值 對于每個根號n以內的質數都要轉移,復雜度$O(\frac{n}{\log n})$

考慮優化,顯然$p_{j+1}>i$的時候,g[i][j]=4(3*1+1)

所以當$pj^{2}>i$的時候,g[i][j]=g[i][j-1]+F(pi) 可以不用轉移,用的時候補上那一段即可。

之所以把f的狀態表示成"后j個",也是出于這個目的?

這樣的復雜度近似是$O(\frac{n^{\frac{3}{4}}}{logn})$

然后線篩出根號n以內的F[],答案是$f[n]+\sum_{i=1}^{\sqrt{n}}F[i]g[\frac{n}{i}]$

#include<iostream> #include<cstdio> #include<cmath> #define MN 320000 #define ll long long using namespace std; inline ll read() {ll x = 0; char ch = getchar();while(ch < '0' || ch > '9') ch = getchar();while(ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();}return x; }int s[MN+5],num=0,last[MN+5],l[MN+5],l0[MN+5],sq,P,N[MN+5]; ll f0[MN+5],f[MN+5],g0[MN+5],g[MN+5],d[MN+5],n; bool b[MN+5];void CalcF() {for(int i=1;i<=sq;++i) f[i]=f0[i]=1;for(int i=P-1;i;--i){for(int j=1;j<=sq&&l[j]>i;++j){ll now=(n/j)/s[i];for(int tms=4;now;now/=s[i],tms+=3){if(now<=sq) f[j]+=tms*(f0[now]+4*(max(0,N[now]-max(i+1,l0[now])+1)));else f[j]+=tms*(f[n/now]+4*max(0,P-max(i+1,l[n/now])));}}for(int j=sq;j&&l0[j]>i;--j){ll now=j/s[i];for(int tms=4;now;tms+=3,now/=s[i])f0[j]+=tms*(f0[now]+4*max(0,N[now]-max(i+1,l0[now])+1));}}for(int i=1;i<=sq;++i) f[i]+=4*(P-l[i]); }void CalcG() {for(int i=1;i<=sq;++i)g0[i]=i,g[i]=n/i;for(int i=1;i<P;++i){for(int j=1;j<=sq&&l[j]>i;++j){ll now=n/j/s[i];if(now<=sq) g[j]-=g0[now]-max(0,i-l0[now]);else g[j]-=g[n/now]-max(0,i-l[n/now]);}for(int j=sq;j&&l0[j]>i;--j)g0[j]-=g0[j/s[i]]-max(0,i-l0[j/s[i]]);}for(int i=1;i<=sq;++i) g[i]-=P-l[i]; }int main() {d[1]=1;for(int i=2;i<=MN;++i){if(!b[i]) s[++num]=last[i]=i;for(int j=1;s[j]*i<=MN;++j){b[s[j]*i]=1,last[s[j]*i]=s[j];if(i%s[j]==0) break;}int sum=1,tms,p;for(int j=i;j>1;){tms=0;p=last[j];for(;j%p==0;j/=p,++tms);sum*=(tms*3+1);}d[i]=sum;N[i]=N[i-1]+(!b[i]);}for(int T=read();T;--T){n=read();sq=sqrt(n);l[sq+1]=0;for(P=1;1LL*s[P]*s[P]<=n;++P);for(int i=1;i<=sq;++i)for(l0[i]=l0[i-1];1LL*s[l0[i]]*s[l0[i]]<=i;++l0[i]);for(int i=sq;i;--i)for(l[i]=l[i+1];1LL*s[l[i]]*s[l[i]]<=n/i;++l[i]);CalcF();CalcG();ll ans=f[1];for(int i=1;i<=sq;++i)ans+=4*d[i]*(g[i]-1);printf("%lld\n",ans);}return 0; }

轉載于:https://www.cnblogs.com/FallDream/p/divcnt3.html

總結

以上是生活随笔為你收集整理的[Spoj]Counting Divisors (cube)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。