RUPC2019参加記 Day1
※この記事は問題のネタバレを含みます
はじめに
立命館大学競技プログラミング合宿2019(RUPC2019)に参加してきました。
こういった競プロの合宿に参加するのは初めてだったのですが、いろいろな人と交流したり、初対面の人と一緒に問題を考察したりするのは楽しかったです。
コンテストも教育的な問題が多く、勉強になりました。
運営の方々、交流してくださった方々ありがとうございました。
コンテスト
@Kutimoti_Tさん、@hogemochiさんと組みました。
初日で緊張していたのですが、声をかけていただいてありがたかったです。
問題は、立命館大学の3時間のセットでした。
コンテストでは、解ける問題を手分けして早めに通せたと思います。
楽しかったです!
— けんしん (@knshnb) March 5, 2019
BEを解いて残り2時間座っていました。。。
Eはreverseして全要素-1倍して、BITを貼って使わないをして、lower_boundでLIS求めるやつやりました https://t.co/yNQiOYt9Cy
C、Dはチームメイトがいつの間にか通してくれていました。
Fが思いつかなかったのが悔しかったですが、勉強になる問題でした。
内容
B: たぬきつね
順番にシミュレーションするだけ
char f(char a, char b) {
if (a == 'T' && b == 'F') return 'F';
return 'T';
}
signed main() {
int n; cin >> n;
vector<char> a(n); REP (i, n) cin >> a[i];
char ans = f(a[0], a[1]);
REPI (i, 2, n) {
ans = f(ans, a[i]);
}
cout << ans << endl;
}
E: LISum
LISをlower_boundを使ったdpで求めると、sumが最も小さいものになります。
よって、sumが最も大きいLISものを求めるには、全要素を-1倍したもののLISを逆から求めればよいです。
signed main() {
int n; cin >> n;
vector<int> a(n); REP (i, n) cin >> a[i], a[i] = -a[i];
reverse(ALL(a));
vector<int> dp(n, 1e17), sum(n + 1, -1);
REP (i, n) {
int idx = lower_bound(ALL(dp), a[i]) - dp.begin();
dp[idx] = a[i];
chmax(sum[idx], (idx == 0 ? 0 : sum[idx - 1]) - a[i]);
}
REP (i, n + 1) {
if (sum[i] == -1) {
cout << sum[i - 1] << endl; return 0;
}
}
}
上で書いたのが想定解だったようですが、セグツリー(BIT)を更新していくだけでも解けるという知見を得ました。
LISをセグツリーで解く方法は応用の幅が広そうです。
F: Absum
コンテスト終わってから@tempura_cppさんから解説を聞いて天才だなあと思いました。
G: イルミネーション
後で通して追記することをここに宣言しておきます。
その他
- 新幹線に乗るときは学割を取りましょう。
- 会場に向かう途中でほげもちさんに会ってお話しました。
- この日の深夜のこどふぉに出てレートを溶かしました。
day2に続きます。