HDU 6428 2018HDU多校賽 第十場 Calculate(莫比烏斯反演 + 積性 + 線性篩)
阿新 • • 發佈:2019-01-08
題意簡單粗暴,讓你求 。
與gcd有關,一般來說都是要上莫比烏斯來反演一下了。具體來說,我們先來推一些式子:
那麼,原式我們就可以寫成:
然後我們再交換一下求和次序:
對於後面這個東西,我們可以發現,對於一個數字x^k,他能夠被d整除,當且僅當,其中pi表示d分解質因子的每一個數字,ai表示對應pi的指數。那麼我麼令,那麼最後的答案就是:
我們注意到,是尤拉函式和莫比烏斯函式的迪利克雷卷積,根據定理,積性函式的迪利克雷卷積也是積性函式,因此
我們令,根據我們之前的推導:,那麼有:
於是:
那麼:
接下來再看這個,這個就是在分解質因子的過程中,記錄一個deg,表示當前質因子的指數。每次這個質因子加一,當發現它%k之後是1,說明此時除以k向上取整會變大,於是
#include<bits/stdc++.h> #define LL long long #define mod 998244353 #define pb push_back #define lb lower_bound #define ub upper_bound #define INF 0x3f3f3f3f #define sf(x) scanf("%d",&x) #define sc(x,y,z) scanf("%d%d%d",&x,&y,&z) #define clr(x,n) memset(x,0,sizeof(x[0])*(n+5)) #define file(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout) using namespace std; const int N = 1e7 + 10; unsigned int p[N],phmu[N],f2[N],f3[N],last[N],deg[N]; bool isp[N]; void init() { int sz=0; phmu[1]=f2[1]=f3[1]=last[N]=1; for(int i=2;i<N;i++) { if(!isp[i]) { f2[i]=f3[i]=p[++sz]=i; phmu[i]=i-2; last[i]=deg[i]=1; } for(int j=1;j<=sz&&(LL)i*p[j]<N;j++) { int x=i*p[j]; isp[x]=1; if(i%p[j]==0) { last[x]=last[i]; deg[x]=deg[i]+1; if (last[i]>1) phmu[x]=phmu[last[i]]*phmu[x/last[i]]; else { if (i>p[j]) phmu[x]=phmu[i]*p[j]; else phmu[x]=(p[j]-1)*(p[j]-1); } f2[x]=f2[i]*(deg[x]%2==1?p[j]:1); f3[x]=f3[i]*(deg[x]%3==1?p[j]:1); break; } else { deg[x]=1; last[x]=i; f2[x]=f2[i]*f2[p[j]]; f3[x]=f3[i]*f3[p[j]]; phmu[x]=phmu[i]*phmu[p[j]]; } } } } int main() { init(); int T; sf(T); while(T--) { int a,b,c; sc(a,b,c); unsigned int ans=0; for(int i=1;i<=a;i++) ans=(ans+phmu[i]*(a/i*(b/f2[i])*(c/f3[i]))); printf("%d\n",ans&((1<<30)-1)); } return 0; }