NOMURA Programming Contest 2022(AtCoder Beginner Contest 253) - AtCoder の参加メモ
B - Distance Between Tokens
2つのo
の位置を見つけてそのマンハッタン距離を計算する
#include <bits/stdc++.h> using namespace std; #define REP(i,n) for(int i=0;i<(n);i++) int main() { int h,w; cin >> h >> w; vector<string> s(h); REP(i,h) cin >> s[i]; vector<pair<int,int>> p; REP(i,h) REP(j,w) if(s[i][j] == 'o') p.emplace_back(i,j); int ans = abs(p[0].first - p[1].first) + abs(p[0].second - p[1].second); cout << ans << endl; return 0; }
C - Max - Min Query
mapで集合Sを管理する。iteratorの最初と最後を参照すればSの最小/最大値が取得できる
#include <bits/stdc++.h> using namespace std; #define REP(i,n) for(int i=0;i<(n);i++) int main() { int q; cin >> q; map<int,int> mp; REP(_,q) { int t; cin >> t; if(t == 1) { int x; cin >> x; mp[x]++; } else if (t == 2) { int x,c; cin >> x >> c; mp[x] = max(0, mp[x]-c); if (mp[x] == 0) mp.erase(x); } else { cout << ((--mp.end())->first - mp.begin()->first) << endl; } } return 0; }
D - FizzBuzz Sum Hard
- 初項がa、末項がl、公差がd、項数がn の等差数列の総和は $ 1/2n(a+l) $ で求められる。
- A の倍数でも B の倍数でもないものの総和 = (1〜Nの総和) - Aの倍数の数列の総和 - Bの倍数の数列の総和 + A,Bの最小公倍数の数列の総和
#include <bits/stdc++.h> using namespace std; #define REP(i,n) for(int i=0;i<(n);i++) using ll = long long; int main() { ll n,a,b; cin >> n >> a >> b; ll ans = (1+n)*n/2; ans -= (a+n/a*a)*(n/a)/2; ans -= (b+n/b*b)*(n/b)/2; ll l = lcm(a,b); ans += (l+n/l*l)*(n/l)/2; cout << ans << endl; return 0; }
E - Distance Sequence
- 動的計画法 + fenwick_tree。fenwick_treeを利用することで区間の要素の総和を O(logN) で求められる。
- a[i] - a[i+1] >= k のケースと a[i+1] - a[i] >= k のケース二通りの範囲を計算しているが、k == 0 の場合には範囲が被るため注意
#include <bits/stdc++.h> #include <atcoder/all> using namespace atcoder; using namespace std; #define REP(i,n) for(int i=0;i<(n);i++) using mint = modint998244353; int main() { int n,m,k; cin >> n >> m >> k; fenwick_tree<mint> dp(m+1); for(int i = 1; i <= m; i++) dp.add(i,1); REP(_,n-1) { fenwick_tree<mint> p(m+1); swap(dp,p); for(int j = 1; j <= m; j++) { if (k == 0) { dp.add(j, p.sum(1,m+1)); continue; } int x1 = j + k; if (x1 <= m) dp.add(j, p.sum(x1, m+1)); int x2 = j - k; if (1 <= x2) dp.add(j, p.sum(1, x2+1)); } } cout << dp.sum(1,m+1).val() << endl; return 0; }