
http://acm.hdu.edu.cn/showproblem.php?pid=5528
题意
定义f(n)=选两个[0,n)的整数a,b,且ab不是n的倍数的方案数
求$g(n) = sum_{d|n}f(d)$。 数据组数1 ≤ $𝑇$ ≤ 20000,1 ≤ $n$ ≤ 10^9。
题解
$f(n) = n^2 - sum_{d|n}phi(frac{n}{d})d$
$g(n) = sum_{d|n}f(d)$
$g(n) = sum_{d|n}(d^2 - sum_{t|d}phi(frac{d}{t})t)$
$g(n) = sum_{d|n}d^2 - sum_{d|n}sum_{i}^{frac{n}{d}}dphi(i)$
$p(n) = sum_{d|n}d^2$
$q(n) = sum_{d|n}sum_{i}^{frac{n}{d}}dphi(i)$
$q(n) = sum_{d|n}dsum_{i}^{frac{n}{d}}phi(i)$
$q(n) = sum_{d|n}d*frac{n}{d} = sum_{d|n}n$
观察可知$p(n)$$q(n)$皆为积性函数,枚举n的素因子再依次求值即可,这样就只剩下了质因子分解的复杂度。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
|
using namespace std; typedef long long ll; const double PI = acos(-1.0); const double eps = 1e-6; const int INF = 1000000000; const int maxn = 100000; int T,n; int tot = 0,num = 0; int vis[maxn+5]; int prime[maxn+5],fac[maxn+5],cnt[maxn+5]; void (){ memset (vis,0,sizeof (vis)); for (int i=2;i<=maxn;i++){ if (!vis[i]){ prime[++tot] = i; for (int j=i;j<=maxn;j+=i){ vis[j] = 1; } } } }
void getfactor (int n){ memset (cnt,0,sizeof(cnt)); for(int i=1;i<=tot && prime[i]*prime[i]<=n;i++){ if (n%prime[i]==0){ fac[++num]=prime[i]; while (n%prime[i]==0){ cnt[num]++; n/=prime[i]; } } } if (n>1){ fac[++num] = n; cnt[num]=1; } }
int main (){ getPrime (); cin >>T; while (T--){ num = 0; scanf ("%d",&n); getfactor (n); ll ans1=1,ans2=1; for (int i=1;i<=num;i++){ ll tmp = 1,tmpx = 1; for (int j=1;j<=cnt[i];j++){ tmp*=fac[i]; tmpx+=tmp*tmp; } ans1 *= tmpx; ans2 *= cnt[i]+1; } printf("%lldn", ans1-n*ans2); } return 0; }
|
近期评论