题目大意
给出一个整数$n$的标准分解,求经过多少次$n=\phi(n)$操作后,可以使$n=1$。标准分解式中,质数$P \le 10^5$,次数$t \le 10^9$。多组数据,最后再输出所有答案中的最大值。
分析
欧拉函数的公式:$\phi(n)=\sum P_i^{t_i-1}\cdot(P_i-1)$,其中$P_i$、$t_i$为标准分解后得到的质因数和对应的次数。
根据欧拉函数的公式可以发现,每次进行$n=\phi(n)$的操作后,所有的质数$P$的次数都减去$1$,然后又多出来$(P-1)$的质因数。而一旦$n$变为$1$,仅当质因数$P$仅有$2$。
因为所有的质因数结果不断地操作,最后都要通过$2$这个媒介再变为$1$,且这个过程中$2$的个数必然大于$0$(因为每次必有一个$P$变为$P-1$,而当$P$不为$2$时,$P-1$必然包含$2$这个因子)。
由于其它质因数变化是和$2$的变化同时进行的,且$2$的变化贯穿这个过程(若原本的$n$包含$2$这个质因子时),而每次操作$2$的次数减一,所以将其它的质数都拆解成2,最后$2$的次数便是答案。
若原本的$n$不包含$2$这个质因子,则第一次操作时$2$的次数不减少(都是$0$),而后面的操作与前面一样,故答案为$2$的次数加一。
实现
根据分析,可以知道最重要的东西是一个数可以拆解为多少个$2$,对此我们假设要拆解的数为$x$,对$x$进行分类讨论。
- 当$x$为偶数时,$x$可拆解出的$2$的个数为$\frac{x}{2}$拆解出的$2$的个数加一。
- 当$x$为奇数时,$x$中不含有$2$这个质因子,所以$\phi(x)$相对$x$而言拆解出的$2$的个数不减少,所以$x$可拆解出的$2$的个数为$\phi(x)$拆解出的$2$的个数。
对于任意一个数$x$,都由小于$x$的数贡献答案,所以递推求就好了。
代码:
1 #include <cstdio> 2 3 int f[100010], phi[100010], two[100010]; 4 int test, n, a, b, flag; 5 long long ans, maxans; 6 7 int main() 8 { 9 for (int i = 2; i < 100000; i++) 10 { 11 if (f[i]) continue; 12 phi[i] = i - 1; 13 for (int j = i + i; j < 100000; j += i) 14 { 15 f[j] = 1; 16 if (phi[j] == 0) phi[j] = j; 17 phi[j] = phi[j] / i * (i - 1); 18 } 19 } 20 for (int i = 2; i < 100000; i++) 21 { 22 if (i % 2 == 0) two[i] = two[i / 2] + 1; 23 else two[i] = two[phi[i]]; 24 } 25 scanf("%d", &test); 26 maxans = 0; 27 while (test--) 28 { 29 scanf("%d", &n); 30 ans = flag = 0; 31 while (n--) 32 { 33 scanf("%d %d", &a, &b); 34 if (a == 2) flag = 1; 35 ans += (long long) two[a] * b; 36 } 37 ans = ans - flag + 1; 38 printf("%lld\n", ans); 39 if (ans > maxans) maxans = ans; 40 } 41 printf("%lld", maxans); 42 }