[HDU5528]Count a * b

题目大意:
  定义函数$f(m)=\displaystyle\sum_{a=0}^{m-1}\sum_{b=0}^{m-1}[m\nmid ab]$,$g(n)=\displaystyle\sum_{m\mid n}f(m)$。
  共有$q(q\leq2\times10^4)$次询问,每次询问$g(n)(n\leq10^9)$的值。

思路:
  对$n$分解质因数,得$n=\displaystyle\prod_{i=1}^rp_i^{q_i}$。
  推公式得$g(n)=\displaystyle\prod_{i=1}^r\frac{(p_i^{q_i+1})-1}{p_i^2-1}-n\prod_{i=1}^r(q_i+1)$。
  先预处理出质数表,然后暴力分解质因数即可。

 1 #include<cstdio>
 2 #include<cctype>
 3 typedef unsigned long long qword;
 4 typedef unsigned __int128 oword;
 5 inline int getint() {
 6     register char ch;
 7     while(!isdigit(ch=getchar()));
 8     register int x=ch^'0';
 9     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
10     return x;
11 }
12 const int M=31628,SIZE=3403;
13 bool b[M];
14 int p[SIZE];
15 inline void init() {
16     for(register int i=2;i<M;i++) {
17         if(!b[i]) {
18             p[++p[0]]=i;
19             for(register int j=i*2;j<M;j+=i) {
20                 b[j]=true;
21             }
22         }
23     }
24 }
25 int main() {
26     init();
27     const int T=getint();
28     for(register int t=1;t<=T;t++) {
29         int n=getint();
30         qword prod1=1,prod2=n;
31         for(register int i=1;p[i]*p[i]<=n;i++) {
32             if(n%p[i]!=0) continue;
33             int q=0;
34             qword tmp=p[i];
35             while(n%p[i]==0) {
36                 n/=p[i];
37                 tmp*=p[i];
38                 q++;
39             }
40             prod2*=q+1;
41             prod1*=((oword)tmp*tmp-1)/(p[i]*p[i]-1);
42         }
43         if(n!=1) {
44             prod1*=(qword)n*n+1;
45             prod2*=2;
46         }
47         printf("%llu\n",prod1-prod2);
48     }
49     return 0;
50 }

 

posted @ 2018-02-05 16:11  skylee03  阅读(107)  评论(0编辑  收藏  举报