【BZOJ2749】[HAOI2012]外星人

Description

Input

Output

输出test行,每行一个整数,表示答案。

Sample Input

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 }

 

 

posted @ 2017-03-26 14:50  cot  阅读(177)  评论(0编辑  收藏  举报