Solution
- 根据贪心策略,可以发现出完一张牌后对手的出牌是固定的。同理可以算出 Monocarp 出完一张牌 \(a\) 后下一次出的牌 \(to_a\)。
- \(a\) 和 \(to_a\) 胜负状态相同。可以发现对所有 \(a\) 建 \(a\to to_a\) 后形成的图是内向基环树,一遍 dfs 即可求出答案。
时间复杂度 \(\mathcal{O}(n\log n)\)(将 \(n,m\) 看作同阶)。
Code
#include <bits/stdc++.h>
#define REP(i, l, r) for (int i = (l); i <= (r); ++ i)
#define DEP(i, r, l) for (int i = (r); i >= (l); -- i)
#define fi first
#define se second
using namespace std;
namespace Milkcat {
typedef long long LL;
typedef pair<LL, LL> pii;
const int N = 1e6 + 5;
LL n, m, suf1[N], suf2[N], qwq[N], to[N], ans[N], res[3]; pii a[N], b[N];
int dfs(int u) {
if (ans[u] != -1) return ans[u];
return ans[u] = 1, ans[u] = dfs(to[u]);
}
int main() {
cin >> n;
REP(i, 1, n) cin >> a[i].fi;
REP(i, 1, n) cin >> a[i].se;
cin >> m;
REP(i, 1, m) cin >> b[i].fi;
REP(i, 1, m) cin >> b[i].se;
sort(a + 1, a + 1 + n);
sort(b + 1, b + 1 + m);
suf1[n + 1] = suf2[m + 1] = 0;
DEP(i, n, 1) suf1[i] = (a[i].se > a[suf1[i + 1]].se ? i : suf1[i + 1]);
DEP(i, m, 1) suf2[i] = (b[i].se > b[suf2[i + 1]].se ? i : suf2[i + 1]);
REP(i, 1, m) qwq[i] = suf1[lower_bound(a + 1, a + 1 + n, pii(b[i].se + 1, 0)) - a];
REP(i, 1, n) {
int x = suf2[lower_bound(b + 1, b + 1 + m, pii(a[i].se + 1, 0)) - b];
if (!x) { ans[i] = 0; continue; }
if (!qwq[x]) { ans[i] = 2; continue; }
to[i] = qwq[x], ans[i] = -1;
}
memset(res, 0, sizeof res);
REP(i, 1, n) {
if (ans[i] == -1) dfs(i);
res[ans[i]] ++;
}
REP(i, 0, 2) cout << res[i] << ' ';
cout << '\n';
return 0;
}
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
int T = 1; cin >> T;
while (T --) Milkcat::main();
return 0;
}
标签:int,题解,REP,suf2,Game,suf1,ans,Infinite,se
From: https://www.cnblogs.com/Milkcatqwq/p/17975410