CF1895E Infinite Card Game 题解

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;
}
posted @ 2024-01-19 19:05  喵仔牛奶  阅读(10)  评论(0编辑  收藏  举报