BZOJ 4454: C Language Practice
4454: C Language Practice
Time Limit: 20 Sec Memory Limit: 24 MBSubmit: 501 Solved: 112
[Submit][Status][Discuss]
Description
Input
第一行输入一个正整数T(T<=85),表示测试数据的组数。
每组数据第一行包含两个正整数n,m(1<=n,m<=2000),表示序列的长度。
第二行包含n个正整数,表示a[0],a[1],...,a[n-1](0<=a[i]<=1000000)。
第三行包含m个正整数,表示b[0],b[1],...,b[m-1](0<=b[i]<=1000000)。
Output
对于每组数据输出一行一个整数,即答案。
Sample Input
3
3 2
5 9 6
3 4
2 2
8 9
0 6
1 1
9
6
3 2
5 9 6
3 4
2 2
8 9
0 6
1 1
9
6
Sample Output
6
22
3
22
3
HINT
注意:此题只有一个数据点。
Source
$O(N)-O(1)$的gcd黑科技
1 #include <cstdio> 2 3 inline char Char(void) 4 { 5 static const int siz = 1024; 6 7 static char buf[siz]; 8 static char *hd = buf + siz; 9 static char *tl = buf + siz; 10 11 if (hd == tl) 12 fread(hd = buf, 1, siz, stdin); 13 14 return *hd++; 15 } 16 17 inline int Int(void) 18 { 19 int ret = 0, neg = 0, c = Char(); 20 21 for (; c < 48; c = Char()) 22 if (c == '-')neg ^= true; 23 24 for (; c > 47; c = Char()) 25 ret = ret * 10 + c - '0'; 26 27 return neg ? -ret : ret; 28 } 29 30 int g[1005][1005]; 31 32 int fac[1000005][3]; 33 34 int pre[1000005], pri[1000005], tot; 35 36 inline int gcd(int a, int b) 37 { 38 if (a <= 1000 && b <= 1000) 39 return g[a][b]; 40 41 int ret = 1; 42 43 for (int i = 0; i < 3; ++i) 44 if (fac[a][i] != 1) 45 { 46 int t = fac[a][i]; 47 48 if (pre[t]) 49 { 50 int d = g[t][b % t]; 51 ret *= d, b /= d; 52 } 53 else if (b % t == 0) 54 ret *= t, b /= t; 55 } 56 57 return ret; 58 } 59 60 signed main(void) 61 { 62 for (int i = 0; i <= 1000; ++i) 63 for (int j = 0; j <= 1000; ++j) 64 if (i == 0 || j == 0) 65 g[i][j] = i + j; 66 else if (g[j][i % j]) 67 g[i][j] = g[j][i % j]; 68 else if (g[i % j][j]) 69 g[i][j] = g[i % j][j]; 70 else if (g[i][j % i]) 71 g[i][j] = g[i][j % i]; 72 else if (g[j % i][i]) 73 g[i][j] = g[j % i][i]; 74 75 fac[1][0] = fac[1][1] = fac[1][2] = 1; 76 77 for (int i = 2; i <= 1000000; ++i) 78 { 79 if (!pre[i])pri[++tot] = i, 80 fac[i][0] = fac[i][1] = 1, fac[i][2] = i; 81 82 for (int j = 1; j <= tot && pri[j] * i <= 1000000; ++j) 83 { 84 int num = pri[j] * i, p = pri[j]; 85 86 pre[num] = p; 87 fac[num][0] = fac[i][0]; 88 fac[num][1] = fac[i][1]; 89 fac[num][2] = fac[i][2]; 90 91 if (fac[num][0] * p <= 1000) 92 fac[num][0] *= p; 93 else if (fac[num][1] * p <= 1000) 94 fac[num][1] *= p; 95 else 96 fac[num][2] *= p; 97 } 98 } 99 100 for (int cas = Int(); cas--; ) 101 { 102 static int n, m, a[2005], b[2005]; 103 104 n = Int(); 105 m = Int(); 106 107 for (int i = 0; i < n; ++i) 108 a[i] = Int(); 109 110 for (int i = 0; i < m; ++i) 111 b[i] = Int(); 112 113 unsigned ans = 0; 114 115 for (int i = 0; i < n; ++i) 116 for (int j = 0; j < m; ++j) 117 ans += gcd(a[i], b[j]) ^ i ^ j; 118 119 printf("%u\n", ans); 120 } 121 }
@Author: YouSiki