题目大意
题目大意
Alice 和 Bob 在玩一个游戏。给定两个数组:包含 n 个元素的数组 a 和包含 m 个元素的数组 b。
两人轮流进行操作,Alice 先手。在每个回合中,玩家需要从数组 a 中选择一个数字 x,并从数组 b 中选择一个数字 y。
选定 x 和 y 后,y 会从数组 b 中被移除(如果数组中存在多个相同的 y,只移除其中一个),而 x 仍然保留在数组 a 中。无法进行合法操作(即无法选出满足自身规则的 x 和 y)的玩家将输掉游戏。
假设双方都采取最优策略,请判断谁会赢得游戏。
输入格式
第一行包含一个整数 t(1≤t≤104),表示测试用例的数量。
对于每个测试用例:
第一行包含两个整数 n 和 m(1≤n,m≤106)。
第二行包含 n 个整数 ai(1≤ai≤n+m),表示数组 a 的元素。
第三行包含 m 个整数 bi(1≤bi≤n+m),表示数组 b 的元素。
保证所有测试用例中 n 的总和以及 m 的总和均不超过 106。
输出格式
对于每个测试用例,输出获胜者的名字:如果 Alice 赢,输出 Alice;如果 Bob 赢,输出 Bob。
样例输入
1 2 3 4 5 6 7 8 9 10
| 3 9 3 3 2 4 2 2 4 4 2 4 6 7 12 10 3 3 2 5 4 2 5 3 4 4 4 10 7 13 1 5 1 1 2 3 4 5
|
样例输出
样例解释
对于第一个测试用例,Alice 的获胜过程如下:
-
Alice 的回合:选择 x=3,y=6(6 能被 3 整除)。操作后 6 从数组 b 中移除,此时 b=[7,12]。
-
Bob 的回合:选择 x=3,y=7(7 不能被 3 整除)。Bob 在这个回合只能选择 y=7,因为对于 y=12,数组 a 中找不到任何不能整除它的 x。操作后 7 从数组 b 中移除,此时 b=[12]。
-
Alice 的回合:选择 x=4,y=12(12 能被 4 整除)。操作后 12 从数组 b 中移除,此时数组 b 变为空。
-
Bob 的回合:数组 b 已经为空,Bob 无法进行任何操作,因此 Bob 输掉游戏,Alice 获胜。
思路讲解
OK,我们说回来。这个D为什么交了5发还是没过呢?主要是因为就是这个D,它的数据量比较大。使用Victor victor或者victor的这种调和级数写法呢,它这个时间会超。可以使用vis 数组标记所有 a 的倍数。这样子可以避免卡常。
1 2 3 4 5 6 7 8 9 10
| ll cnt_un_divide=0,cnt_all_divide=0; vector<char> vis(N+M+2); for (auto a:A) { for (ll i=1;i<=N+M;++i) { if (i*a>N+M) { break; } vis[i*a]=true; } }
|
然后为什么标题里面提了不要用 while 循环?是因为涉及累加的逻辑(在 D 的对拍暴力程序当中),直接 continue 以后,while 循环的这个累加就崩掉了。
AC代码
AC
https://codeforces.com/contest/2203/submission/364454955
源代码
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 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
|
#include <bits/stdc++.h> #define all(vec) vec.begin(),vec.end() #define lson(o) (o<<1) #define rson(o) (o<<1|1) #define SZ(a) ((long long) a.size()) #define debug(var) cerr << #var <<" = ["<<var<<"]"<<"\n"; #define debug1d(a) \ cerr << #a << " = ["; \ for (int i = 0; i < (int)(a).size(); i++) \ cerr << (i ? ", " : "") << a[i]; \ cerr << "]\n"; #define debug2d(a) \ cerr << #a << " = [\n"; \ for (int i = 0; i < (int)(a).size(); i++) \ { \ cerr << " ["; \ for (int j = 0; j < (int)(a[i]).size(); j++) \ cerr << (j ? ", " : "") << a[i][j]; \ cerr << "]\n"; \ } \ cerr << "]\n"; #define cend cerr<<"\n-----------\n" #define fsp(x) fixed<<setprecision(x)
using namespace std;
using ll = long long; using ull = unsigned long long; using DB = double; using i128 = __int128; using CD = complex<double>;
static constexpr ll MAXN = (ll)2e6+10, INF = (1ll<<61)-1; static constexpr ll mod = 998244353; static constexpr double eps = 1e-8; const double pi = acos(-1.0);
ll lT,testcase;
i128 lcm128(i128 a,i128 b) { i128 res=a*b/__gcd(a,b); return res; }
void Solve() { ll N,M; cin >> N >> M; vector<ll> A(N),B(M); for (int i=0;i<N;++i) { cin>>A[i]; } for (int i=0;i<M;++i) { cin>>B[i]; } sort(all(A)); A.resize(unique(all(A))-A.begin()); __int128 acc_lcm=A[0]; for (int i=1;i<A.size();++i) { acc_lcm=lcm128(acc_lcm,A[i]); } ll cnt_un_divide=0,cnt_all_divide=0; vector<char> vis(N+M+2); for (auto a:A) { for (ll i=1;i<=N+M;++i) { if (i*a>N+M) { break; } vis[i*a]=true; } } for (int i=0;i<M;++i) { if (!vis[B[i]]) { cnt_un_divide++; } }
for (int i=0;i<M;++i) { if (B[i]%acc_lcm==0) { cnt_all_divide++; } }
ll rem=M-cnt_all_divide-cnt_un_divide; for (int idx=1;;++idx) { if (idx&1) { if (rem>0) { rem--; continue; } if (cnt_all_divide>0) { cnt_all_divide--; continue; } cout<<"Bob\n"; return; }else { if (rem>0) { rem--; continue; } if (cnt_un_divide>0) { cnt_un_divide--; continue; } cout<<"Alice\n"; return; } } }
signed main() { ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); #ifdef LOCAL cout.setf(ios::unitbuf); #endif cin >> lT; for (testcase=1;testcase<=lT;++testcase) Solve(); return 0; }
|
心路历程(WA,TLE,MLE……)

后面还被系统测试阴了一手,把这个LCM改成128,用INT128就可以了,这个叫什么,当时其实我就知道这里应该是会有点问题的,想用这个128嘛,但是可能还是犹豫还是犹豫了。
1 2 3 4
| i128 lcm128(i128 a,i128 b) { i128 res=a*b/__gcd(a,b); return res; }
|