【BZOJ2749】[HAOI2012]外星人
Description
Input
Output
输出test行,每行一个整数,表示答案。
Sample Input
1
2
2 2
3 1
2
2 2
3 1
Sample Output
3
HINT
Test<=50 Pi<=10^5,1<=Q1<=10^9
Solution
我们考虑phi的式子,每次变换就是把每一个质数减一乘上指数减一次方。最后的目标是把所有的都变成1,而只有2可以变成1。
然后我们设f[i]为i这个数需要多少次可以变成1,我们发现f是一个积性函数,可以用线性筛来解决。
Code
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <cmath> 5 6 #ifdef WIN32 7 #define LL "%I64d" 8 #else 9 #define LL "%lld" 10 #endif 11 12 #ifdef CT 13 #define debug(...) printf(__VA_ARGS__) 14 #define setfile() 15 #else 16 #define debug(...) 17 #define filename "" 18 #define setfile() freopen(filename".in", "r", stdin); freopen(filename".out", "w", stdout) 19 #endif 20 21 #define R register 22 #define getc() (S == T && (T = (S = B) + fread(B, 1, 1 << 15, stdin), S == T) ? EOF : *S++) 23 #define dmax(_a, _b) ((_a) > (_b) ? (_a) : (_b)) 24 #define dmin(_a, _b) ((_a) < (_b) ? (_a) : (_b)) 25 #define cmax(_a, _b) (_a < (_b) ? _a = (_b) : 0) 26 #define cmin(_a, _b) (_a > (_b) ? _a = (_b) : 0) 27 #define cabs(_x) ((_x) < 0 ? (- (_x)) : (_x)) 28 char B[1 << 15], *S = B, *T = B; 29 inline int F() 30 { 31 R char ch; R int cnt = 0; R bool minus = 0; 32 while (ch = getc(), (ch < '0' || ch > '9') && ch != '-') ; 33 ch == '-' ? minus = 1 : cnt = ch - '0'; 34 while (ch = getc(), ch >= '0' && ch <= '9') cnt = cnt * 10 + ch - '0'; 35 return minus ? -cnt : cnt; 36 } 37 #define maxn 100010 38 int f[maxn], pr[maxn], prcnt, p[maxn], q[maxn]; 39 int main() 40 { 41 // setfile(); 42 f[1] = 1; 43 for (R int i = 2; i <= 100000; ++i) 44 { 45 if (!f[i]) {pr[++prcnt] = i; f[i] = f[i - 1];} 46 for (R int j = 1; j <= prcnt; ++j) 47 { 48 if (pr[j] * i > 100000) break; 49 f[pr[j] * i] = f[i] + f[pr[j]]; 50 if (i % pr[j] == 0) break; 51 } 52 } 53 for (R int t = F(); t; --t) 54 { 55 R int m = F(); 56 R bool flag = 1; 57 R long long ans = 0; 58 for (R int i = 1; i <= m; ++i) 59 { 60 p[i] = F(); 61 q[i] = F(); 62 ans += 1ll * f[p[i]] * q[i]; 63 flag &= p[i] & 1; 64 } 65 printf("%lld\n", ans + flag ); 66 } 67 return 0; 68 }