[题目链接]
https://www.lydsy.com/JudgeOnline/problem.php?id=2749
[算法]
首先 , 每次对一个数x进行操作 , 只会使该数减少一个2的因子
那么 , 我们只需考虑每个数可以分解为多少个2 :
设gi表示i可以分解为多少个2
当gi为质数时 : gi = gi-1
否则 , 若gi = ab , 则gi = g(a) + g(b)
线性筛预处理即可
时间复杂度 : O(N + TM)
[代码]
#include<bits/stdc++.h> using namespace std; const int MAXP = 1e5 + 10; typedef long long ll; typedef long double ld; typedef unsigned long long ull; int tot; int p[MAXP] , q[MAXP] , f[MAXP] , prime[MAXP]; ll g[MAXP]; template <typename T> inline void chkmin(T &x , T y) { x = min(x , y); } template <typename T> inline void chkmax(T &x , T y) { x = max(x , y); } template <typename T> inline void read(T &x) { T f = 1; x = 0; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == ‘-‘) f = -f; for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - ‘0‘; x *= f; } int main() { int T; g[1] = 1; for (int i = 2; i < MAXP; i++) { if (!f[i]) { f[i] = i; prime[++tot] = i; g[i] = g[i - 1]; } for (int j = 1; j <= tot; j++) { int tmp = i * prime[j]; if (tmp >= MAXP) break; f[tmp] = prime[j]; g[tmp] = g[i] + g[prime[j]]; if (prime[j] == f[i]) break; } } read(T); while (T--) { int n; read(n); ll ans = 0; bool flg = false; for (int i = 1; i <= n; i++) { read(p[i]); read(q[i]); flg |= (p[i] == 2); ans += 1ll * g[p[i]] * q[i]; } if (!flg) ++ans; printf("%lld\n" , ans); } return 0; }
原文地址:https://www.cnblogs.com/evenbao/p/10360355.html
时间: 2024-10-13 23:10:55