BZOJ 1408: [Noi2002]Robot
1408: [Noi2002]Robot
Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 545 Solved: 364
[Submit][Status][Discuss]
Description
Input
Output
Sample Input
3
2 1
3 2
5 1
2 1
3 2
5 1
Sample Output
8
6
75
6
75
HINT
90号机器人有10个老师,加上它自己共11个。其中政客只有15号;军人有3号和5号;学者有8个,它们的编号分别是:2,6,9,10,18,30,45,90。
Source
吓呆我,这是NOI水平?2002年的啊……
发现x的独立数就是phi(x),而x的老师就是x的约数。
因为$\sum_{d|n}{\phi(d)}=n$,所以只需要求出前两个答案就可以得到最后一个。
前两个只和$p_{i}$有关,和其指数$e_{i}$无关,且任意两个p都是互质的,有$\phi(p_{i})*\phi(p_{j})=\phi(p_{i}*p_{j})$。
所以前缀和维护之前的奇数和偶数个p组成的phi的和即可。
1 #include <cstdio> 2 3 const int mxn = 1005; 4 const int mod = 10000; 5 6 template <class T> 7 __inline void read(T &x) 8 { 9 x = 0; 10 char c = getchar(); 11 while (c < 48)c = getchar(); 12 while (c > 47)x = x*10 + c - 48, c = getchar(); 13 } 14 15 inline int pow(int a, int b) 16 { 17 int r = 1; 18 19 for (; b; b >>= 1, a = a * a % mod) 20 if (b & 1)r = r * a % mod; 21 22 return r; 23 } 24 25 int n; 26 int m = 1; 27 int p[mxn]; 28 int e[mxn]; 29 int ans[2]; 30 int sum[2]; 31 32 signed main(void) 33 { 34 read(n); 35 36 for (int i = 1; i <= n; ++i) 37 read(p[i]), read(e[i]); 38 39 for (int i = 1; i <= n; ++i) 40 m = m * pow(p[i], e[i]) % mod; 41 42 sum[0] = 1, sum[1] = 0; 43 44 for (int i = 1; i <= n; ++i)if (p[i] & 1) 45 { 46 --p[i]; 47 48 int s0 = sum[0]; 49 int s1 = sum[1]; 50 51 (ans[0] += p[i] * s1) %= mod; 52 (ans[1] += p[i] * s0) %= mod; 53 54 (sum[0] += s1 * p[i]) %= mod; 55 (sum[1] += s0 * p[i]) %= mod; 56 } 57 58 printf("%d\n%d\n%d\n", ans[0], ans[1], ((m - ans[0] - ans[1] - 1) % mod + mod) % mod); 59 }
@Author: YouSiki