Bondo416さんのAtCoder Beginner Contest 261での成績:667位
— ボンド@競プロ (@bond_cmprog) July 23, 2022
パフォーマンス:1698相当
レーティング:1420→1451 (+31) :)#AtCoder #ABC261 https://t.co/XvcncLevR6
A - Intersection
$ L_1 \leq x \leq R_1 $ かつ $ L_2 \leq x \leq R_2 $ を満たす個数 $ cnt $ を数え、$ \max(0, cnt-1) $ が答え
void solve(){ int l1, l2, r1, r2; cin >> l1 >> r1 >> l2 >> r2; int cnt = 0; REP(i,101) { if(l1 <= i and i <= r1 and l2 <= i and i <= r2) { cnt++; } } cout << max(0, cnt-1) << endl; }
B - Tournament Result
問題文の通りに矛盾があるかどうかを全探索で判定をする
void solve(){ int N; cin >> N; vector<string> S(N); REP(i,N) cin >> S[i]; bool ok = true; REP(i,N) REP(j,i+1,N) { if(S[i][j] == 'W' and S[j][i] != 'L') ok = false; if(S[i][j] == 'L' and S[j][i] != 'W') ok = false; if(S[i][j] == 'D' and S[j][i] != 'D') ok = false; } cout << (ok ? "correct" : "incorrect") << endl; }
C - NewFolder(1)
mapで文字列が出現した個数をカウントしていく
void solve(){ int N; cin >> N; map<string, int> mp; REP(i,N) { string s; cin >> s; if(mp.count(s)) cout << s << '(' << mp[s] << ')' << endl; else cout << s << endl; mp[s]++; } }
D - Flipping and Bonus
$ dp[i][j] := i $ 回目のコイントスまで行ったときにカウンタの値が $ j $ である時の最大値としてDPを行う
void solve(){ int N, M; cin >> N >> M; vector<int> X(N); REP(i,N) cin >> X[i]; vector<int> Y(N+10); REP(i,M) { int c, y; cin >> c >> y; Y[c] = y; } vector dp(N+10, 0LL); REP(i,N) { vector nxt(N+10, 0LL); for(int j=0;j<=i;j++) { chmax(nxt[0], dp[j]); chmax(nxt[j+1], dp[j] + X[i] + Y[j+1]); } swap(nxt, dp); } cout << *max_element(ALL(dp)) << endl; }
E - Many Operations
bitごとに独立なのでbitごとで考える
操作前のbitが立っている・立っていない場合で $ i $ 回目まで操作したときの結果(そのbitが立っているかいないか)は一意に定まるのでこれを前計算で求めておく
$ i $ 回目のクエリには今の値 $ X $ の立っているbitごとに前計算した値を更新していけばいい
void solve(){ int N, C; cin >> N >> C; vector<int> T(N), A(N); REP(i,N) cin >> T[i] >> A[i]; vector on(30, vector(N, 0)); vector off(30, vector(N, 0)); REP(b,30) { int o = 1; int x = 0; REP(i,N) { if(T[i] == 1) { o &= (A[i] >> b & 1); x &= (A[i] >> b & 1); } else if(T[i] == 2) { o |= (A[i] >> b & 1); x |= (A[i] >> b & 1); } else { o ^= (A[i] >> b & 1); x ^= (A[i] >> b & 1); } on[b][i] = o; off[b][i] = x; } } int X = C; REP(i,N) { int tmp = 0; REP(j,30) { if(X >> j & 1) tmp |= (on[j][i] << j); else tmp |= (off[j][i] << j); } cout << tmp << endl; X = tmp; } }
F - Sorting Color Balls
色を気にしない場合のコストは転倒数であるのでこれを求めておく
同じ色の場合はコストが掛からないので同じ色間での転倒数を全体の転倒数から引いていく
void solve(){ int N; cin >> N; vector<int> C(N), X(N); vector<vector<int>> v(303030); REP(i,N) cin >> C[i]; REP(i,N) cin >> X[i]; BIT<ll> bit(303030); ll ans = 0; REP(i,N) { ll inv = i - bit.sum(X[i]+1); ans += inv; bit.add(X[i], 1); } set<int> st; REP(i,N) { st.insert(C[i]); v[C[i]].emplace_back(X[i]); } for(auto x : st) { vector<int> cmp; for(auto y : v[x]) cmp.emplace_back(y); sort(ALL(cmp)); cmp.erase(unique(ALL(cmp)), cmp.end()); BIT<ll> bitx(cmp.size()+1); REP(i,v[x].size()) { int idx = lower_bound(ALL(cmp), v[x][i]) - cmp.begin(); ans -= i - bitx.sum(idx+1); bitx.add(idx, 1); } } cout << ans << endl; }