HDU 4746 Mophues(莫比烏斯反演)
阿新 • • 發佈:2018-08-27
pri 質因子 clas while 二維 sizeof name 等於 swap
\(\sum_{k|d}u(\frac{d}{k})\)可以預處理得到。
由於限制了質因子的個數,並且我們還想用分塊的方法求出最後答案,於是設\(sum(a,b):\sum_{i=1}^{a}\sum_{k|i且k質因子個數\leq j}u(\frac{i}{k})\)。在打出莫比烏斯函數表後,可以在預處理出\(sum(a,b)表\),由於1e6以內的數質因子個數不會超過20,因此第二維開到20即可。
那麽計算結果時可以分塊加速求出ans的值。
題意:求\(1\leq i \leq N,1\leq j \leq M,gcd(i,j)\)的質因子個於等於p的對數。
分析:加上了對質因子個數的限制。
設\(f(d):[gcd(i,j)=d]\) , \(F(d):[d|gcd(i,j)]\) ,k是滿足質因子<=p的數。
則\(ans = \sum_{k}f(k) = \sum_{k}\sum_{k|d}u(\frac{d}{k})\lfloor \frac{N}{d}\rfloor \lfloor\frac{M}{d}\rfloor = \sum_{d}\lfloor \frac{N}{d}\rfloor \lfloor\frac{M}{d}\rfloor\sum_{k|d}u(\frac{d}{k})\)
\(\sum_{k|d}u(\frac{d}{k})\)可以預處理得到。
由於限制了質因子的個數,並且我們還想用分塊的方法求出最後答案,於是設\(sum(a,b):\sum_{i=1}^{a}\sum_{k|i且k質因子個數\leq j}u(\frac{i}{k})\)。在打出莫比烏斯函數表後,可以在預處理出\(sum(a,b)表\),由於1e6以內的數質因子個數不會超過20,因此第二維開到20即可。
那麽計算結果時可以分塊加速求出ans的值。
#include<bits/stdc++.h> using namespace std; typedef long long LL; const int maxn=5e5+5; bool vis[maxn]; int prime[maxn],mu[maxn]; int sum[maxn][20]; int pricnt[maxn]; void init(){ memset(vis,false,sizeof(vis)); mu[1] = 1; prime[0] = 0; int cnt=0; for(int i=2;i<maxn;++i){ if(!vis[i]){ mu[i] = -1; pricnt[i] = 1; prime[++cnt] = i; } for(int j=1;j<=cnt;++j){ if(i*prime[j] >= maxn) break; pricnt[i*prime[j]] = pricnt[i]+1; vis[i*prime[j]] = true; if(i % prime[j]){ mu[i*prime[j]] = -mu[i]; } else{ mu[i*prime[j]] = 0; break; } } } } void prepare(){ for(int i=1;i<maxn;++i){ for(int j= i;j<maxn;j+=i){ sum[j][pricnt[i]] += mu[j/i]; } } for(int i=1;i<maxn;++i){ for(int j =0;j<20;++j){ sum[i][j] +=sum[i-1][j]; } } for(int i=1;i<maxn;++i){ for(int j=1;j<20;++j){ sum[i][j] +=sum[i][j-1]; } } } LL gao(LL n,LL m,LL p) //枚舉p { LL ans = 0; for(int i=1,j;i<=n;i=j+1){ j = min(n/(n/i),m/(m/i)); ans += (sum[j][p]-sum[i-1][p])*(n/i)*(m/i); } return ans; } int main() { #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); freopen("out.txt","w",stdout); #endif init(); prepare(); LL N,M,p; int T; scanf("%d",&T); while(T--){ scanf("%lld %lld %lld",&N, &M,&p); LL res=0; if(p>=20){ res = N*M; } else{ if(N>M) swap(N,M); res = gao(N,M,p); } printf("%lld\n",res); } return 0; }
HDU 4746 Mophues(莫比烏斯反演)