BZOJ 2749 HAOI 2012 外星人 数论 欧拉函数

题意:

给出一个数,给出的形式是其分解质因数后,对应的质因数pi及其次数qi,问对这个数不停求phi,直至这个数变成1,需要多少次。(多组数据)

范围:pi <= 1e5,qi <= 1e9

分析:

  当x > 2时,phi[x]均为偶数。而每次求phi之后,2的次数只会减一,然后其他的质因数分解出多个2,因此数x分解得到的2的个数就是答案了。

  如果一开始不存在质因数2,那么需要多进行一次phi操作。

程序:

 1 #include <cstdio>
 2 #include <cstdlib>
 3 #include <cstring>
 4 #include <string>
 5 #include <algorithm>
 6 #include <iostream>
 7 
 8 using namespace std;
 9 
10 #define REP(i, a, b) for (int i = (a), i##_end_ = (b); i <= i##_end_; ++i)
11 #define mset(a, b) memset(a, b, sizeof(a))
12 const int maxn = 1e5;
13 typedef long long LL;
14 int prime[maxn+10], pcnt, g[maxn+10];
15 bool isNotPrime[maxn+10];
16 
17 void prepare()
18 {
19     pcnt = 0, mset(isNotPrime, 0);
20     REP(i, 2, maxn)
21     {
22         if (!isNotPrime[i])
23         {
24             prime[++pcnt] = i;
25             g[i] = (i == 2) ? 1 : g[i-1];
26         }
27         REP(j, 1, pcnt)
28         {
29             if (i*prime[j] > maxn) break ;
30             isNotPrime[i*prime[j]] = true;
31             g[i*prime[j]] = g[i]+g[prime[j]];
32             if (i%prime[j] == 0) break ;
33         }
34     }
35 }
36 
37 int main()
38 {
39     prepare();
40     int T;
41     scanf("%d", &T);
42     while (T --)
43     {
44         int m;
45         scanf("%d", &m);
46         LL ans = 0; int flag = 0;
47         while (m --)
48         {
49             int p, q;
50             scanf("%d %d", &p, &q);
51             flag |= (p == 2);
52             ans += (LL)g[p]*q;
53         }
54         printf("%lld\n", ans+(!flag));
55     }
56     return 0;
57 }
View Code

 

转载于:https://www.cnblogs.com/-ZZB-/p/6592709.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值