Codeforces Round #189 (Div. 1)
解いたらまとめを書いていこうと思った。
茶会1にて。1完。
A. Malek Dance Club
実験した。
本番はc++で書いた。与えられる2進数100桁整数の取り扱いが面倒だった。実際バグらせてかなり手間取った。LLつよい。
#!/usr/bin/env python3
p = 1000000007
s = input()
print(int(s,2) * pow(2, len(s) - 1) % p)
B. Psychos in a Line
本番解けず。editorialより。
要約: i
番目の人は、彼より左にいて彼より強くて彼に最も近い人をj
番目の人とすると、開区間(j,i)
に含まれる人が全員死んだ次の時刻に死ぬ。
#include <iostream>
#include <vector>
#include <stack>
#include <algorithm>
#define repeat_from(i,m,n) for (int i = (m); (i) < (n); ++(i))
#define repeat(i,n) repeat_from(i,0,n)
using namespace std;
int main() {
int n; cin >> n;
vector<int> a(n); repeat (i,n) cin >> a[i];
vector<int> t(n); // i番目の人の死ぬ時間
stack<int> s; // indexに関して昇順、強さに関して降順
repeat (i,n) {
// この時点で、sの中の誰かがiを殺す
t[i] = 1;
while (not s.empty() and a[s.top()] < a[i]) {
t[i] = max(t[i], t[s.top()] + 1); // while脱出後にmax_elementするとO(n^2)
s.pop();
}
// この時点で、開区間(s.top(),i)内の人は全てiより弱い
if (s.empty()) {
t[i] = 0; // 自分より左に自分より強い人がいない
}
s.push(i);
}
cout << *max_element(t.begin(), t.end()) << endl;
return 0;
}
先輩はrange minimum query使ってた。editorialにはrandom-access doubly linked list上でsimulationしても解けるよってあった。
-
部内の練習会 ↩