zgg与占卜师

题目大意

 
给出一个整数$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 }

 

转载于:https://www.cnblogs.com/lightning34/p/4600863.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值