题目
给定两个数组 a a a 和 b b b ,以及多个查询 k k k (默认 k k k 为质数),判断在以下规则下,小 X 和小 Z 谁会获胜:
小 X 从 a a a 中选一个能被 k k k 整除的数。
小 Z 从 b b b 中选一个能被 k k k 整除的数。
比较两者选的数的大小,大的一方获胜。
思路
使用线性筛预处理所有质数。
对于每个 a [ i ] a[i] a [ i ] 和 b [ i ] b[i] b [ i ] ,分解其质因数,并记录每个质因数对应的最大数。
如果 a a a 中没有数能被 k k k 整除,小 Z 获胜。
如果 a a a 中有数能被 k k k 整除,且 b b b 中没有,小 X 获胜。
否则,比较 a a a 和 b b b 中能被 k k k 整除的最大数,大的一方获胜。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 #include <bits/stdc++.h> using namespace std;const int N=5e5 +10 , MAX=8e6 +10 ;int n, m, q, a[N], b[N], max_a[MAX], max_b[MAX];bool che[MAX];vector<int > pri; void init () { for (int i=2 ; i<MAX; i++) { if (!che[i]) pri.push_back (i); for (int p : pri) { if (i*p >= MAX) break ; che[i*p] = true ; if (i%p == 0 ) break ; } } } int main () { ios::sync_with_stdio (0 ); cin.tie (0 ); init (); cin >> n >> m >> q; for (int i=1 ; i<=n; i++) { cin >> a[i]; int x = a[i]; for (int p : pri) { if (p*p > x) break ; if (x%p == 0 ) { max_a[p] = max (max_a[p], a[i]); while (x%p == 0 ) x /= p; } } if (x > 1 ) max_a[x] = max (max_a[x], a[i]); } for (int i=1 ; i<=m; i++) { cin >> b[i]; int x = b[i]; for (int p : pri) { if (p*p > x) break ; if (x%p == 0 ) { max_b[p] = max (max_b[p], b[i]); while (x%p == 0 ) x /= p; } } if (x > 1 ) max_b[x] = max (max_b[x], b[i]); } while (q--) { int k; cin >> k; if (che[k]) cout << "Z\n" ; else { if (max_a[k] == 0 ) cout << "Z\n" ; else if (max_b[k] == 0 || max_a[k] >= max_b[k]) cout << "X\n" ; else cout << "Z\n" ; } } return 0 ; }