题意:
给出一个数,给出的形式是其分解质因数后,对应的质因数pi及其次数qi,问对这个数不停求phi,直至这个数变成1,需要多少次。(多组数据)
范围:pi <= 1e5,qi <= 1e9
分析:
当x > 2时,phi[x]均为偶数。而每次求phi之后,2的次数只会减一,然后其他的质因数分解出多个2,因此数x分解得到的2的个数就是答案了。
如果一开始不存在质因数2,那么需要多进行一次phi操作。
程序:
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <algorithm>
#include <iostream> using namespace std; #define REP(i, a, b) for (int i = (a), i##_end_ = (b); i <= i##_end_; ++i)
#define mset(a, b) memset(a, b, sizeof(a))
const int maxn = 1e5;
typedef long long LL;
int prime[maxn+], pcnt, g[maxn+];
bool isNotPrime[maxn+]; void prepare()
{
pcnt = , mset(isNotPrime, );
REP(i, , maxn)
{
if (!isNotPrime[i])
{
prime[++pcnt] = i;
g[i] = (i == ) ? : g[i-];
}
REP(j, , pcnt)
{
if (i*prime[j] > maxn) break ;
isNotPrime[i*prime[j]] = true;
g[i*prime[j]] = g[i]+g[prime[j]];
if (i%prime[j] == ) break ;
}
}
} int main()
{
prepare();
int T;
scanf("%d", &T);
while (T --)
{
int m;
scanf("%d", &m);
LL ans = ; int flag = ;
while (m --)
{
int p, q;
scanf("%d %d", &p, &q);
flag |= (p == );
ans += (LL)g[p]*q;
}
printf("%lld\n", ans+(!flag));
}
return ;
}