エイシング プログラミング コンテスト 2020 感想
問題
感想
4完だったけど、ちょっと早かったので久しぶりに温まった。やったね!
最近のABC難しすぎひんか???5完以上できない回が続いてる。
平成ABCの傾斜に近いという声もあったが、確かにそんな感じがする。
やったぜ!
— スコル (@scol_kp) 2020年7月11日
scolさんのエイシング プログラミング コンテスト 2020での成績:538位
パフォーマンス:1803相当
レーティング:1505→1538 (+33) :)#AtCoder #エイシングプログラミングコンテスト2020 https://t.co/usSZEqWoM2
A - Number of Multiples
でも解けるけど、脳死で全探索を書くのが速い。
リンク: https://atcoder.jp/contests/aising2020/submissions/15142182提出コード
void solve() {
ll L, R, D;
cin >> L >> R >> D;
ll ans = 0;
for (ll i = L; i <= R; i++) {
if (i % D == 0) {
++ans;
}
}
cout << ans << "\n";
}
B - An Odd Problem
前から丁寧に確かめていく。
リンク:https://atcoder.jp/contests/aising2020/submissions/15146652提出コード
void solve() {
ll N;
cin >> N;
Vl A(N + 1);
for (ll i = 1; i <= N; i++) {
cin >> A[i];
}
ll ans = 0;
for (ll i = 1; i <= N; i++) {
if (i & 1 && A[i] & 1) {
++ans;
}
}
cout << ans << "\n";
}
C - XYZ Triplets
10分くらい解法が思いつかなかった。因数分解できることを願ってWolframAlphaに投げたら
僕「x2 + y2 + z2 + xy + yz + zx を因数分解するとどうなりますか?」
Wolframくん「x2 + y2 + z2 + xy + yz + zx を因数分解すると x2 + y2 + z2 + xy + yz + zx になります。」
僕「そう......」
という悲しい思いをした。で、制約と式をよく見ると、 のみを考えれば良いことに気づき、全探索を書いてACを得た。 全探索で行けるかどうかぐらいは最初に確認しましょう(笑)。 このとき、順位表を見ると2000位くらいで冷や汗をかいた。
リンク:https://atcoder.jp/contests/aising2020/submissions/15158903提出コード
void solve() {
ll N;
cin >> N;
Vl cnts(N + 1);
for (ll i = 1; i <= 100; i++) {
for (ll j = 1; j <= 100; j++) {
for (ll k = 1; k <= 100; k++) {
ll t = i * i + j * j + k * k + i * j + j * k + k * i;
if (t > N) continue;
++cnts[t];
}
}
}
for (ll i = 1; i <= N; i++) {
cout << cnts[i] << "\n";
}
}
D - Anything Goes to Zero
なので、操作はすぐに終了することがわかる。 各操作さえ高速に処理できればそのままシミュレートしてもよさそうだな~~という気持ちになる。
で、操作を実装しようとしたときに一つ問題がでてきて、1回目の操作が厄介なことに気づく。 2200000 くらいの超巨大な数の剰余を求めなければならない。 2回目以降は 32bit 整数の範囲でふつうに計算できる。
を愚直に求めようとすると、1回目の操作、すなわち、超巨大な数の剰余を求めることを 最大で 200000 回くらいしなければならない。 これは間に合わない。
落ち着いて考えると、 or であって、また、 も の和で表されるから、 を または で割ったときの余りを前計算しておけば、 差分計算によって、各 における1回目の操作の結果を高速に求めることができる。
また、 のビットが1つしか立ってないとき、操作を全くしないことがあるので、実装時にはそれに気を付ける必要がある。(これにちゃんと気づけた。えらい!!)
これACできたとき、天才!!!ってなったけど、コンテストが終わってみると結局1500人も解いていた......。天才が1500人いたということやな!!競プロ界、天才が多すぎる。
リンク:https://atcoder.jp/contests/aising2020/submissions/15167363提出コード
using bs = bitset<200010>;
void solve() {
ll N;
cin >> N;
string S;
cin >> S;
bs base;
for (ll i = 0; i < N; i++) {
if (S[i] == '1') {
base[N - 1 - i] = true;
}
}
ll pcnt = base.count();
ll pcnt1 = pcnt + 1;
ll pcnt2 = pcnt - 1;
if (pcnt2 == 0) {
pcnt2 = -1;
}
Vl rs1(N), rs2(N);
ll cur1 = 1;
ll cur2 = 1;
for (ll i = 0; i < N; i++) {
rs1[i] = cur1;
cur1 *= 2;
cur1 %= pcnt1;
rs2[i] = cur2;
cur2 *= 2;
cur2 %= pcnt2;
}
//+
ll r1 = 0;
for (ll i = 0; i < N; i++) {
if (base[i]) {
r1 += rs1[i];
}
}
r1 %= pcnt1;
//-
ll r2 = 0;
for (ll i = 0; i < N; i++) {
if (base[i]) {
r2 += rs2[i];
}
}
r2 %= pcnt2;
for (ll i = N - 1; i >= 0; i--) {
if (pcnt == 1 && base[i]) {
cout << 0 << "\n";
continue;
}
ll r;
if (base[i]) {
r = (r2 - rs2[i] + pcnt2) % pcnt2;
}
else {
r = (r1 + rs1[i]) % pcnt1;
}
ll cnt = 1;
while (r > 0) {
ll c = __builtin_popcountll(r);
r %= c;
++cnt;
}
cout << cnt << "\n";
}
}
E - Camel Train
なので、 を求めて貪欲っぽくするんだろうな~~とは思えたものの、どうやって埋めていけば良いかがよくわからず、解けなかった......。
後でACする予定。ACしてから続きを書く。
F - Two Snukee
見ていないけど、順位表を見ると橙の方が解けていないのでかなり難しかったみたいだ。