宇都宮ライトレール (2023/12/18)

宇都宮ライトレールに乗りました。

ライトレールとは?

「ライトレール」とは公共道路上の軌道と専用の軌道を併用する鉄道方式で、LRT (Light Rail Transit) と呼ばれたりもします。路面電車と比較すると、専用軌道を持つところや、運行距離が長く輸送力が大きいという特徴があります。日本国内には、富山ライトレールと今回紹介する宇都宮ライトレールがあります。

宇都宮ライトレール

宇都宮ライトレール(正式には宇都宮芳賀ライトレール線)は、第三セクターである宇都宮ライトレール株式会社が運営するライトレールで、2023 年 8 月 26 日に開業しました。上下分離方式を採用していて、上部(鉄道の運行などの運営)を宇都宮ライトレール株式会社が、下部(車両や軌道などの鉄道インフラ)を宇都宮市などの自治体が管理しています。

宇都宮ライトレールは、宇都宮駅東口 (A) を起点として、途中鬼怒川を渡った後ゆいの杜 (B) を経由して、終点の芳賀・高根沢工業団地 (C) へと向かいます。運行距離は 14.6 km で、乗り通す際の所要時間は約 50 分、料金は 400 円で、ラッシュ時間帯は毎時 7-8 本、日中は毎時 5 本が走行しています。

出典:国土地理院ウェブサイト

乗車記

朝ゆっくり出たので宇都宮駅には 12 時過ぎに着きました。早速ライトレールのある東口に向かいましたが、広場ができていたり新たな商業施設が複数できていたりと、以前来たときと比べてかなり再開発が進んでいるようで驚きました。食事をしてから乗車する予定でしたが、行こうとしていた店が満席だったので、とりあえず乗ることにしました。

宇都宮駅東口駅は東口を出てすぐのエスカレーターを降りたところにあります。駅自体に改札はなく、乗降時に IC カードをタッチすることで決済するというシステムになっています。

乗降時に決済する。乗車時の方が下にあるのが非自明

この日は昼過ぎでしたがかなり盛況していて、始発駅から 3 両編成の車内を自由には歩けないくらい人が乗っていました。国内では最新の鉄道なので、中には乗車を目的に来た人もいたであろうと思います。

車内の様子(空いているときに撮影)

宇都宮駅東口駅を出ると最初に 90 度回りますが、その後は概ね直線的に進んでいきます。1 両がそこそこ長いので、ここのカーブはかなりきつそうな感じがします。座席や揺れ方など、乗車しているときの感覚は車やバスに近く、通常の鉄道との違いが感じられました。

座席はレンタカーの席みたいな感じ

開業して間もないので当然と言えばそうですが、車内はかなり綺麗でした。

照明は N700S みたいな感じ

同行していた t 氏が 14 時から面談をやらないといけないようだったので、宇都宮大学に向かうべく宇都宮駅東口から 2 駅先の駅東公園前で降りました。この辺りは住宅が多く立ち並んでいて、ライトレールに需要があるのもうなづけるという感じでした。途中駅のホームは、バス停のように上下線で離れた位置にあるのが特徴的です。

車両の全長。道路の中央にある軌道を走る

降車してからはまず近くにあった餃子の店に行きました。私自身も定期的に餃子を作っていて、店で食べる餃子より自分で作ったものの方が美味しいことが多いのですが、さすが宇都宮だけあって美味しく頂けました。

焼餃子と揚餃子(900 円)

食事後は予定通り宇都宮大学に向かいます。大学構内に入ったくらいのタイミングで急に腹痛に見舞われたので、t 氏が空き教室で面談をしている間、教室とトイレを反復することになりました。トイレに入ってから 1,2 分しか経っていないタイミングで外から大声で何者かが「早くしろよ」と言うのが聞こえて戦慄したのを覚えています。

15 時くらいに面談が終わると、宇大を後にして今度は峰駅に向かいました。ライトレールの 2 駅先に「宇都宮大学陽東キャンパス」駅があるのに実際の最寄りはこの峰なのを不思議に思っていましたが、今回行ったのは峰キャンパスですぐ近くに別のキャンパスがあったということだったようです。

日が暮れる前に乗り通しておきたかったので、峰駅からは終点の芳賀・高根沢工業団地駅まで直接向かいます。この時間帯はかなり空いていて快適に乗ることができました。

列車は途中で大通りを離れて専用軌道に入って鬼怒川を渡り、ゆいの杜付近でまた大通りと合流します。確かにただ大通りを走るだけだとわざわざ鉄道を作る意味も薄いので、通りの南側の需要を拾っているという側面もありそうです。

専用軌道で鬼怒川を渡る

終点の芳賀・高根沢工業団地に着くまではそこそこ時間がかかりました。工業団地という名前の通り工場らしき建物が並んでいますが、この辺りには主にホンダの工場があるようです。

終点の芳賀・高根沢工業団地。右に見えるのはホンダの駐車場っぽい

ただでさえ最高気温が 10 度にも満たない寒さなのに、聳え立つ工場の影響で日当たりも悪かったので、付近の散策は諦めて即折り返すことにします。帰りはゆいの杜で途中下車しました。降りてみた所感で、道路や建物が新しいものばかりであることに気づきました。実際にゆいの杜は 21 世紀に開発されたニュータウンで、このライトレールの建設が決まってから発展してきたようです。

降車後はライトレールとは別れて鬼怒川を目指しました。鬼怒川までは 3 km 程度と意外と距離があり、辿り着く頃には日が暮れそうになっていましたが、橋の上には富士山や上毛三山が眺望できる雄大な景色が広がっていました。道中は非常に寒かったですが来て良かったなと思います。

鬼怒川。左奥には富士山が見えている(低画質すみません)

ゆいの杜に戻ってきてからはカフェで食事をし、18 時過ぎの便で宇都宮に帰りました。列車は夕方の上りにも関わらず座席はすべて埋まっているくらい混雑していましたが、宇都宮まで電車に乗ってきてライトレールの沿線に通勤・通学するという需要もかなりありそうに感じました。

宇都宮駅東口。お疲れ様でした

19 時前に宇都宮まで戻ってきました。この時間でも在来線で余裕を持って東京に帰れるのも良いです。

感想

近未来感があって面白かったです。富山や他の市電も行ってみたいですね。

第10回 SQLコンテスト (2023/12/16)

第 10 回 SQL コンテストに参加しました。最終結果は 3 完 60 点で 10 位でした。

終結

近況報告

10 月以降はほとんど何もしてなかったので、結構忘れている部分が多いです。2 ヶ月に 1 回というペースだと、ちょうど忘れた頃にやってくるので厳しいところはありますが、定期的に復習できるという面では良いかもしれません。

コンテストの振り返り

問題 1

文字列から _ を取り除くことができればよいです。これを実現できる関数がありそうなので、調べてみると TRIM 関数でできることがわかります。開始 4 分後に AC。

SELECT
    EMP_CODE AS CODE,
    "'" || TRIM(EMP_KANA_NAME, '_') || "'" AS KANA_NAME
FROM
    EMP
ORDER BY
    EMP_CODE DESC

問題 2

受注件数と受注金額の合計を GROUP BY で求めれば良いです。上位 5 件のみを表示するという部分が面倒ですが、順位付けをして 5 位以上のみを残すという方法を取りました。開始 17 分後に AC。2 問目という位置にしては要求される事項が多いと思いました。

後で知りましたが LIMIT 5 を最後につけることで上位 5 件のみを表示できるようです。

WITH T AS(
    SELECT
        ORDERS.CUST_CODE AS CODE,
        CUST_NAME AS NAME,
        COUNT(*) AS CNT,
        SUM(ORDER_AMNT) AS TTL_AMT,
        ROUND(1.00 * SUM(ORDER_AMNT) / COUNT(*)) AS AVG_AMT,
        RANK() OVER(ORDER BY
            COUNT(*) DESC,
            ROUND(1.00 * SUM(ORDER_AMNT) / COUNT(*)) DESC,
            ORDERS.CUST_CODE ASC
        ) AS RNK
    FROM
        ORDERS
        INNER JOIN
            CUSTOMER ON ORDERS.CUST_CODE = CUSTOMER.CUST_CODE
    WHERE
        ORDER_DATE BETWEEN '2023-09-01' AND '2023-09-30'
    GROUP BY
        ORDERS.CUST_CODE
    ORDER BY
        CNT DESC,
        AVG_AMT DESC,
        CODE ASC
)
SELECT
    CODE,
    NAME,
    CNT,
    TTL_AMT,
    AVG_AMT
FROM
    T
WHERE
    CNT >= 5 AND RNK <= 5

問題 3

全ての年の情報が含まれるテーブルから、各年のデータを別々の列に表示するというタイプの問題です。こういうときは CASE 句が非常に便利です。順位は欠番なしなので DENSE_RANK を使わなければいけない点に要注意。コピペと修正を繰り返すのがかなり面倒でしたが、割と素直な問題だったので開始 33 分後に AC。

WITH T AS(
    SELECT
        HOUSEHOLD_SURVEY.AREA_CODE AS CODE,
        AREA.AREA_NAME AS NAME,
        ROUND(100.0 * SUM(
            CASE SURVEY_YEAR
                WHEN 2022 THEN FOOD_EXP
                ELSE 0
            END
        ) / SUM(
            CASE SURVEY_YEAR
                WHEN 2022 THEN CONSUMPTION_EXP
                ELSE 0
            END
        ), 1) AS "2022_RATIO",
        ROUND(100.0 * SUM(
            CASE SURVEY_YEAR
                WHEN 2017 THEN FOOD_EXP
                ELSE 0
            END
        ) / SUM(
            CASE SURVEY_YEAR
                WHEN 2017 THEN CONSUMPTION_EXP
                ELSE 0
            END
        ), 1) AS "2017_RATIO",
        ROUND(100.0 * SUM(
            CASE SURVEY_YEAR
                WHEN 2012 THEN FOOD_EXP
                ELSE 0
            END
        ) / SUM(
            CASE SURVEY_YEAR
                WHEN 2012 THEN CONSUMPTION_EXP
                ELSE 0
            END
        ), 1) AS "2012_RATIO"
    FROM
        HOUSEHOLD_SURVEY
        INNER JOIN
            AREA ON HOUSEHOLD_SURVEY.AREA_CODE = AREA.AREA_CODE
    GROUP BY
        HOUSEHOLD_SURVEY.AREA_CODE
)
SELECT
    CODE,
    NAME,
    DENSE_RANK() OVER(ORDER BY "2022_RATIO" ASC) AS "2022_RANK",
    "2022_RATIO" || '%' AS "2022_RATIO",
    DENSE_RANK() OVER(ORDER BY "2017_RATIO" ASC) AS "2017_RANK",
    "2017_RATIO" || '%' AS "2017_RATIO",
    DENSE_RANK() OVER(ORDER BY "2012_RATIO" ASC) AS "2012_RANK",
    "2012_RATIO" || '%' AS "2012_RATIO"
FROM
    T
ORDER BY
    "2022_RANK" ASC,
    CODE DESC

問題 4

3 問終わって残り 26 分だったので、上手くいけば全完できそうかという状況です。

問題としては、各 SESSION_ID について EX_TIMESTAMP でソートした後に、STEP1, STEP2,..., STEP5 がこの順に最大で何個並ぶかを求められればよいです。この問題に対して、以下のようなアルゴリズムを考えました。

  • SESSION_IDPROCESS_ID の組であって、自身より番号が小さい全ての STEP と比べて EX_TIMESTAMP が大きく、自身より番号が大きい全ての STEP と比べて EX_TIMESTAMP が小さいもののみを残す。
  • SESSION_IDPROCESS_ID の組であって、自身より番号が小さい全ての STEP がテーブルに含まれているもののみを残す。

この考察自体は正しかったのですが、正当性がそれほど明らかではないのと、実装に手こずったので時間内には間に合いませんでした。問題文に明記されていものの、答えが 0 になる STEP も表示しないといけないという制約があり、そこをどうするかはすぐには考え付きませんでした。最終的には全て 0 の表を作ってから外部結合するという手法を取りました。

WITH T1 AS(
    SELECT
        SESSION_ID,
        CAST(SUBSTR(PROCESS_ID, -1) AS INTEGER) AS PROCESS_ID,
        EX_TIMESTAMP,
        MAX(EX_TIMESTAMP) OVER(
            PARTITION BY SESSION_ID
            ORDER BY PROCESS_ID ASC
        ) AS PRE_TIME,
        MIN(EX_TIMESTAMP) OVER(
            PARTITION BY SESSION_ID
            ORDER BY PROCESS_ID DESC
        ) AS NEXT_TIME
    FROM
        PROCESS_LOG
),
T2 AS(
    SELECT
        SESSION_ID,
        PROCESS_ID,
        COUNT(*) OVER(
            PARTITION BY SESSION_ID
            ORDER BY PROCESS_ID ASC
        ) AS PRE_CNT
    FROM
        T1
    WHERE
        EX_TIMESTAMP = PRE_TIME
        AND EX_TIMESTAMP = NEXT_TIME
),
T3 AS(
    SELECT
        MAX(PROCESS_ID) AS PROCESS_ID,
        COUNT(*) AS CNT
    FROM
        T2
    WHERE
        PROCESS_ID = PRE_CNT
    GROUP BY
        PROCESS_ID
),
T4 AS(
    SELECT
        1 AS PROCESS_ID
    UNION ALL
        SELECT
            PROCESS_ID + 1 AS PROCESS_ID
        FROM T4
        WHERE
            PROCESS_ID < 5
)
SELECT
    'STEP' || T4.PROCESS_ID AS PROCESS,
    CASE
        WHEN T3.CNT IS NULL THEN 0
        ELSE T3.CNT
    END AS CNT
FROM
    T4
    LEFT OUTER JOIN
        T3 ON T4.PROCESS_ID = T3.PROCESS_ID

感想

実装力が足りない。。。

ICPC 2023 アジア地区予選 横浜大会 (2023/11/25-26)

 ICPC 2023 アジア地区予選 横浜大会にチーム DELIAIR (torisasami, tokusakurai, sapphire15) で参加しました。最終結果は 9 完で 8 位でした。

終結

チーム結成まで

DELIAIR は 2021 年 4 月に結成しました。それまでの経緯を簡単にまとめてみます。

torisasami との出会い

torisasami とは大学に入学したとき (2019) のクラスが一緒でした。私が競プロを始めて間もない 10 月頃に torisasami のスマホのお気に入りに atcoder があるのを見て勝手に開いたら、黄色間近の青だったのでかなりびっくりしたのを覚えています。それ以降は torisasami に色々教えてもらいながら勉強していきました。この頃は緑から茶色に落ちたりしてモチベーションが下降気味だったので、torisasami との出会いがなければ競プロを続けていたかはかなり怪しかったと思います。

ICPC 2020 参加未遂

その後は torisasami と切磋琢磨して両者黄色にまでなり、クラスメイトもう一人を合わせて 2020 年の 11 月頃の国内予選に参加を考えていました。ICPC サイトに登録はしていたものの、誰も ICPC の練習をしていなかったり、そもそもコンテストシステムがどのようなものなのかを知らなかったため、結果として参加は見送ることになりました。

sapphire15 の加入

もう一人のクラスメイトは、進学先の学科の授業が忙しくて競プロと疎遠になってしまい、その後は ICPC のことはしばらく考えていませんでした。2021 年 3 月に torisasami が橙になったタイミングで「今年は ICPC 出たいね」という話を持ち掛けたら、twitter でチームメイトを募集してくれました。そこに同学年の sapphire15 が駆けつけてくれ、DELIAIR が結成しました。もっとも、チーム名が決まったのは夏頃なのですが。

今大会への意気込み

結成当初は大学 3 年で、みんなでコドフォバチャを毎日のようにやったりと競プロのモチベが高く、全員上を目指してどんどん力をつけていったと思います。この年度の地区予選は出場が叶わなかったものの、Give us sociablity のコドフォジムでのバチャ練習に頻繁に首を突っ込んだりしていたのもいい思い出です。

大学 4 年になって、みんな研究室に配属されたり院試があったりと、競プロばかりやってないで将来を考えないといけない時期になってきます。torisasami と私はそれでもコンテストやバチャに定期的に行っていましたが、sapphire15 はこの辺りから競プロモチベも落ちてきたようで、私もチーム練習に無理に誘うのは申し訳ないという気持ちを持つようになりました。そんな中でも、Universal Cup の登場によってチーム戦で顔を合わせる機会が増えたのは本当にありがたいことでした。

大学卒業後は全員大学院に進学したので、もう 1 年このチームでやれることになりました。しかし、torisasami や私もインターンなどを通してついに社会を意識するようになり、もうこれで終わりなんだな、就職なり D 進なりみんなそれぞれの道に別れていくんだな、という気持ちは日に日に強まっていきました。

 

思い返せば、このチームで 2 年半やってきて、楽しかったこと、悔しかったこと、面白かったこと、意見が合わなかったこと、嬉しかったこと、革命が起きたこと、起きなかったことなど、本当に色々なことがありました。全員同学年で、互いに言いたいことを好きなだけ言い合える関係にあったのは恵まれていたと思います。

余程のことが起きなければ今大会が最後の ICPC。正直に言うと、地区予選が終わって欲しくないという気持ちがありました。

そうは言っても時の流れを止めることはできないので、大会に向けてできる限りのことはやりたい、本番では後悔したくないという思いは強く持っていて、それは 2 人にも伝わっていたと思います。

大会に向けての練習

今年は Universal Cup や multiuni があったので、チーム戦練習は主にそちらで行いました。特に、練習では以下のことを意識しました。

  • US 配列を使う
  • ライブラリは毎回写経する(写経しやすいライブラリを作る)
  • チーム内で役割分担をはっきりする

US 配列については 2 ヶ月間これしか使わずに練習をやりましたが、もう JIS 配列を使えなくなるくらいには使いこなせるようになりました。

ライブラリの写経についても、AOJ ICPC も含めて色々な問題をやっていたら、自然と遅延セグ木をソラ書きできるくらいにはなりました。

役割分担については、各人の得意分野に基づいて以下のようにすることにしました。

  • sapphire15: 問題の考察(特に初手の方針)の案を出す、構築をする
  • torisasami: 問題文を読解する、sapphire15 の考察を議論して詰める
  • tokusakurai: 大雑把な解法の実装を具現化する、高度典型っぽい問題の考察

大会前の Univerdsal Cup 2 回は、torisasami の家に行って対面で練習をやりました。

 

5h コンの経験を通して、最終的なチームとしての戦略は以下の通りになりました。

  • tokusakurai が最初に環境構築をする
  • torisasami と sapphire15 はそれぞれ最初に B 問題、A 問題を解き、それ以降は別々に問題を読み進める
  • 実装は基本的に tokusakurai が担当する。2 人が入出力形式とざっくりした概要、アルゴリズムを教えてくれれば後は何とかする
  • torisasami が自信がある場合は実装を任せる場合もある
  • ライブラリ写経も tokusakurai がやる
  • パズル系の構築は sapphire15 に任せる
  • 2 人で同じ問題を考えているのに進まないとロスが大きいので、出来るだけ同時に 2 問以上考えている状態を維持する。

torisasami 得意の adhoc な数え上げや sapphire15 の得意な構築パズルが出ればいい所まで行けるのではないかと予想していました。

大会 1 日目 (11/25 土)

横浜上陸

朝 9 時に起床し、爪切りや支度をして 10 時頃に家を出て会場に向かった。10 時 40 分頃に横浜駅に到着したので、昨年同様会場までぶらぶら歩いて行くことにした。曇りで気温も低く、あいにくの天気であったが、それでも横浜の街はどこにでも人が溢れかえっているような賑わいを見せていた。さすが土日である。夏にインターンに行った某社の横浜オフィスを発見してここにあるのかーと思うなどして、ぶらぶらと torisasami と待ち合わせをしている桜木町駅まで歩く。待ち合わせの 12 時までには少し時間があったので、すぐ近くにある横浜北仲ノットの 46 階展望台へと足を運んだ。以前東京都庁に登った際、友人に横浜に無料で登れるマンションがあるという噂を聞いていたので、一度行ってみたかった場所である。

46 階展望台から。ランドマークタワーを横に見るのは初めて

エレベーターは古いものだったので、昇降だけでもだいぶ時間がかかった。降りた後は 12 時も近かったので桜木町駅に戻ったのだが、なんと torisasami が既にいて驚きを隠せなかった。彼とはもう 4 年以上の付き合いだが、待ち合わせをして間に合ってきたのは初めてかもしれない。

桜木町駅を出てからは、汽車道を進んで会場の横浜産貿ホールマリネリアを目指した。赤レンガ倉庫もまた賑わっていたが、残念ながらスケートリンクの営業には一週間早かった。30 分程歩いて会場近くのザ・ラーメン屋に到着する。やはりこれがないと ICPC は始まらないというものだ。驚くべきことにザ・ラーメン屋は満席だった。並んでいる間暇だったので、会場近くに来ていると言っている sapphire15 を誘って三人で一緒に入店した。

毎年恒例のザ・ラーメン屋。毎年新メニューを謳われている麻婆麺

大会初日

食事を終えるとすぐに会場に向かう。会場はすぐ近くにあり、入ると SPJ の Kite_kuma くんがチームメイトの到着を待たされていたので、ほくそ笑みながら先に入室した。チームの席は昨年同様一番前だった。入ったら最初にチーム紹介ドキュメントを見たが、The Raspberry Candies の所にしれっと "DELIAIR = rniya fan club" と書いてあるのを見つけて早々に気分を害した。

少しするとコーチの Irvan 先生が来る。とても気さくで面倒見の良い、素晴らしい先生だ。先生とは挨拶を交えた後、他のチームはまだ来てないのかと聞かれたため「うちの大学は時間にルーズなやつばかりですみません」と謝っておいた。他チームは先生に心配かけさせていることを反省してほしい。

その後は、他の東大チームや夏合宿で交流があったチームなどと少しお話をした後、開会式が始まった。内容はそんなに覚えていないが、インタラクティブ用のツールがあるということには驚いた。

そうこうしている間にリハーサルコンテストが始まった。コンテストでは、CLion のライセンス認証で苦戦して sapphire15 に怒られるなどした後、テンプレートと実行用のシェルスクリプトを書いて約 1 時間で 4 問全てを解いた。余った 1 時間で、torisasami に印刷してきてもらったライブラリの写経をした。セグ木、遅延セグ木、modint、NTT、HLD を書くことができたのでいいタイピング練習になった。

リハーサルが終わった後はチーム紹介が始まった。事前に準備していたチームとそうでないチームで二分化されている印象があったが、私は少し用意していたことを喋った。海外チームの方にも DELIAIR の意味が伝わっていれば幸いである。海外チームは台湾が多く、韓国やベトナムのチームがいないのが意外だった。

DELI下 AIR太郎 シーズン2

解散後

1 日目のプログラムが終わった後はまずホテルへと向かった。ホテルは torisasami が 9 月に airbnb で予約した"ルームイン上海"というところで、家を宿泊施設として貸しているようなところだった。怪しい名前だったので不安だったが、ひとまず無事に泊まれそうなところだったので安心した。

ルームイン上海。右側にはバルコニーがある

ホテルに荷物を置いた後は中華街に繰り出した。食べ放題に行きたかったが、1000 円台の店は怪しい所ばかりだったので結局昨年行ったのと同じ店に行った。店では研究や研究室の話になり、純粋だった DELIAIR も人生のステップを上がっているんだなという感慨に浸った。

食事を終えてホテルに戻ると、今度はホテルに備え付けのタオルと着替えを持って銭湯に向かった。湯加減の良いジャグジーで torisasami から聞いた AOJ ICPC の問題を考えたり、明日の作戦について話し合ったりした。

銭湯を上がった後はコンビニでヤクルト1000 (torisasami 推し) と明日の朝食のパンとおにぎりを買ってホテルに戻った。その後はなぜか torisasami の高校同期と通話することになり、一時間程通話した後 23:30 頃に就寝した。しかし、下の階に泊まっている人たちの出入りの音がうるさく、1 時間以上は寝付けなかった。睡眠も数時間に一回起きてしまうようなものであったが、布団が柔らかかったので体は十分休めることができた。

大会 2 日目 (11/26 日)

ICPC の朝は早い。朝 7 時半に起床し、食事をしてから会場へ向かう。外は雨が降っており、rainy って rniya の並び替えだなとか意味の分からないことを言っている間に会場に到着した。

部屋に入るやいなやトイレに行きたくなった。行ってみると ICPC 参加者で長蛇の列が形成されており、ホテルで用を足さなかったことを後悔した。本当はやってはいけなかったかもしれないが、2 階のトイレを貸していただいて事なきを得た。

そんなこんなで、持ち込んだノートを復習してたりしたらあっという間にコンテスト開始時刻になった。

コンテスト

前日の反省を生かしてサクッと CLion の環境構築を済ませ、テンプレートとシェルスクリプトを書いた。2 人には並行して問題の読解・考察を進めてもらった。

A 問題の内容は YOKOHAMA の作り方の数え上げだということを sapphire15 から聞き、dp を書いた (0:20 AC)

続く B 問題は、長さ 2C 以下の遷移だけ見ればいいという考察を torisasami から聞き、累積和と dp を書くと通った (0:30 AC)

次に F 問題の内容を sapphire15 から聞いたが、これは \mathbb{F}_2 上の rank 1 行列なのでいつものという感じである (0:44 AC)

D 問題は、sapphire15 は初見で「構文解析だ!」と声を上げていたが、違ったようである。torisasami が解法を詰めていて、区間 DP で解けるという。それはそうなので、実装してみるとまさかの WA。落ちる原因がわからず、コードを印刷して torisasami にも確認してもらうが、間違っているところはない。問題を確認すると、BNF に 1 という文字が入っていないのに異変を感じ、2 桁以上の数字は使えないことに気づいて AC (1:04 AC)。ここでの 3 人全員の足止めは痛恨となった。

残りで解けている問題は K だけらしいのでそちらに向かう。話を聞くと、円の内点を見つけることさえできればあとはできそうだったので、丁寧に実装をした。ジャッジ側で用意されているインタラクティブツールがとても便利で助かった (1:31 AC)

G,E,C で 3 問数え上げがあると聞いたので、modint ライブラリを書いた。こういう場面でソラ書き出来るというのは心強い。E も G も解けそうだが、E はまだ微妙に詰め切れていないようなので先に G をやることに。sapphire15 がメモ化再帰で全部やればいいので、実際そうだなと思って書いてみると通る (1:56 AC)

E 問題も解けそうということなので内容を聞く。基本的には bit DP で、a_i,c_i が両方含まれているあるいは両方含まれていない場合に b_i を入れてはいけないという条件になるということを torisasami から聞く。私はその時点で O(2^n\cdot n) に落とす方法が見えたので、書いてみると通る (2:10 AC)

ここまでで既に 11 問中の 7 問を正解していて昨年の 5 問を優に超えているわけだが、順位は 7-10 位程度で解いても解いても一向に上がらない。このような早解きコンテストでは、序盤の遅れがどんどん積み重なってくるのが非常に辛い。

H 問題は torisasami が見えていて、燃やす埋めるになりそうというので、とりあえず最大流を写経して確認してもらう。考察の話を聞くと、実際に燃やす埋めるの形に帰着で来ているので書いてみる。サンプルの出力が答えの約 2 倍になるのでおかしいなと数分考えてしまったが、ペアを重複カウント & 同じもの同士のペアもカウントしてしまっていた。修正するとサンプルが合ったので、提出 (2:58 AC)

残りはもう 3 問しかなく、順位表的に解かれているのは I と J。J は貪欲で良さそうと 2 人が言う。もしこの貪欲が正しければ HLD + 遅延セグ木で解けるので、とりあえずそれを書いてみることにした。この 2 つの写経は AOJ ICPCDo use segment tree と全く同じ状況なので、その問題のタイムアタックをしていた甲斐があったなと思ってなんだか嬉しかった。実装は 30 分くらいでできたが、提出すると WA が出る。冷静にコードを見返すと、遅延セグ木で頂点 i に該当する情報をそのまま i 番目の点に入れてしまっていたのに気づき、修正して提出するとまたも WA が出る。この辺りで、貪欲も良く考えたら嘘くさくないかと思うようになり、反例を考えるもそちらもなかなか作れないという歯痒い状況に陥ってしまった。

J は貪欲が嘘だと沼なので、より解かれている I に一旦向かうことにした。torisasami は濃度でソートして貪欲でできないかということを考えていたが、私は見た目が LP なのでそちらの線で考えてみることにした。sapphire15 が双対を取ったらどうか?と言ってきたので、丁寧に行列表現に書き下して双対を取ってみる。その間に sapphire15 が J の貪欲の証明ができたと言うので改めてコードを見返してみると、遅延セグ木の初期化の部分を修正していたつもりがまだ間違っていたのに気づいて蒼ざめた。再修正して提出すると今度は AC (4:19 AC)。このミスはあまりにも初歩的すぎて本当に申し訳なかった。

残った時間で I を考えていたが、双対 LP をこねくり回しても釈然としない。torisasami は最後の希望にかけて自明な必要条件を書く。ラスト 2 分でサンプルがあって提出するも、さすがにそれで通るほど ICPC は甘くない。ここでタイムアップとなった。

Yes / No

今年は全体的な難易度が低めだったせいか、順位が全然確定せず、全チーム Yes で 2 周目に入るという状況が何度か起きていたのが面白かった。前半の企業賞は台湾チームのラッシュだったのも凄い巡り合わせだなと思った。

9 チームが 9 完以上ということで、Yes / No でも順位は 1 つしか上がらず、最終順位は 8 位だった。しかし幸運にも OptTech 社から企業賞をもらうことができたのは非常に嬉しかった。

Speed Star は Yes / No の結果がどうであれ優勝が確定していたが、最後の C 問題も通して唯一の全完を決めていて流石の一言だった。World Finals でも存分に暴れてきてほしい。

コンテストを振り返って

昨年の ICPC を見るに 7 完・8 完の勝負になると思っていたが、実際は 9 完・10 完の勝負というのは全く想像もしていなかった。D・J 両問でのロスは非常に悔やまれるが、それがなければ I や C が解けたかというとそうではないとも思う。

もちろん悔しい気持ちで一杯ではあるが、DELIAIR として全力を出し切ったつもりではあるし、何より周りのチームがとても強かったので、この結果を素直に受け入れるしかないと思う。最後にやらかすのがなんとも DELIAIR らしい。

懇親会

昨年とは違い食事付きの懇親会だった。

インターンでお世話になった某社には挨拶しに行こうと思ったので、まずそちらに行った。人事の方や社員の m さんとコンテストの結果について少し話した後、会社の宣伝を頼まれてクリアファイルと会社説明をいくつかもらった。

その後は食事を始めた。食事はあり得ないくらい大量にあったが、麺やポテトなどの炭水化物が特に多かった印象がある。気になっている企業のブースを見に行ったり、インターン先で知り合った競技プログラマーたちと話したりしているうちに、スポンサー賞の OptTech の方から声をかけて頂いた。話があるから後で企業ブースに来いということである。

取った分の食事をいったん済ませてから、チームメイトを揃えて OptTech 社のブースに行った。広告代理店ということで、機械学習を用いて最適な広告を選ぶという事業を行っているという話だった。気になった点を少し質問した後、記念撮影をしていただいた。

 

企業ブースを離れた後は、近くにいた早稲田勢の方に足が吸引されてしまった。早稲田は 2 チーム 4 人(コーチ含)の 8 人とかっつさんの合計 9 人がいたので「早稲田も人が多いですね」と言ったところ、層が厚い世代が抜けてだいぶ人が減っているという話を聞いた。suta さん、ikefumy さん、siro53 さんのお三方は初対面だったが、tokusakurai ですと名乗ると、全員に知ってますと言ってもらえて嬉しかった。色々なお話をさせてもらったが、「ikefumy さんが、学業崩壊して機航に放り込まれた hotman さんとかっつさんを反面教師にした」という話と「Hyado さんが英語の授業で誰も PC を使ってないのに一人だけ最前列でパソカタをしていたり、床に座り込んで競プロをしてた」という話が特に印象に残っている。卒業してもネタが尽きないさすがの sociability だ。かっつさんの仕事の話も色々聞いたが、ここに書くのは控えておく。

食事 3 周目を取った後は、某社の企業ブースに行って r さんから仕事の話を聞いた。ヒューリスティック的な問題の中でも離散最適化を交えたアプローチをされているということを聞いて面白そうだなと思った。昨年に続いてタンブラーを頂いた。

近くに東大チームが集まっていたのでそちらに顔を出した。nok0 さん (26 位) が ALGO ARTIS ARC の懇親会の話をしていて、私 (41 位) も行きます的なことを言ったところ、torisasami (23 位) がそんなメール来てないと言う。登録情報を確認していると、なんとメールアドレスを登録していないことが発覚し、DELIAIR はこういうところがダメだと改めて思わされた。

最後はまた早稲田勢のところに混ぜてもらって話をしていたが、あっという間に終了時刻になった。B1 のお二人も元気そうで良かった。今後の ICPC での活躍に期待。食事は予想通り半分以上余っている感じだったので、予算を割く場所を間違えてないかと思ったりもした。

解散後

ICPC 横浜大会の全てのプログラムが終わった。解散後は真っ直ぐ帰る気になれなかったので SPJ の 3 人と tabr, torisasami の計 6 人で中華街方面のカフェへと歩を運んだ。Kite_kuma くんは我々と The Raspberry Candies が引退することに萎えていたので、SPJ も一緒に引退することを勧めた。Kite_kuma くんが D 進したりしなかったりするらしいが、それはさておき 3 人とも社会には全然興味がなさそうで面白かった。自分も一年前はそんな感じだったかもしれない。

人と話している間は疲れを感じることはなかったが、電車で皆と別れた後はどっと疲れが湧き出て危うく乗り過ごしそうになった。

ICPC 引退

年齢制限のため ICPC はこれで最後となりました。

もっと練習しておけば良かったという気持ちもありますが、最後が他チームと比べて相対的に苦手なセットだったのでツキがなかったかなと思います。

同大学から最大 3 チームという制限によって Asia playoff に参加できないということになっていたら相当悔しかったはずですが、Speed Star が見てて気持ちが良くなるほどの圧勝劇を繰り広げてくれたためすっきり引退することができました。

 

チームを組んでくれた 2 人には本当に感謝しています。torisasami はいつもしょうもない話で楽しませてくれて、sapphire15 は深い知見や考察で幾度となくチームを助けてくれました。気の置けないチームメイトと 2 年半やれて本当に楽しかったんだな、と全てが終わった今になって初めて気付かされました。かなり緩いチームだったので、革命を起こすためにはもっと厳しくやる必要があったかな。

同じ大学で歳の近いライバルチームである SPJ・The Raspberry Candies の存在も、私たちの ICPC 人生を彩ってくれました。彼らの存在がなければこれほど ICPC に熱くなることはなかったと思います。大体同時期に競プロを始めて ICPC に参加し、国内予選での同校制限の壁を乗り越えて、こうして二年連続で一緒に地区予選に出ている仲間 (敵) が何人もいたのは本当に恵まれていたと思います。一緒に引退しましょう。

 

ICPC に選手として参加することはもうありませんが、来年以降もコーチ・スタッフ・スポンサーなど何らかの形で大会に関わっていけたらと思います。

長文になりましたが、ICPC 引退の結びとさせていただきます。これまでお世話になった全ての方々に感謝申し上げます。

ICPC 2023 アジア地区予選 横浜大会 戦前記

いよいよ明日・明後日ということで生存報告も兼ねて。

DELIAIR 近況報告

tokusakurai

今月はインターン・就活・研究室セミナー発表・輪講発表があり、どれも真面目に取り組まなければならなかったため競プロに割ける時間はだいぶ短かった。それでも週末は UCup に参加し、AOJ ICPC の 800-1000 点辺りをボチボチ埋めたりしてコンディションとしては本番に向けて整ってきている。合宿以降 US 配列のタイピング練習やライブラリ写経練習も継続的にやっているので、当日睡眠不足にならなければ割とやれるかなという手応えはある。

torisasami

今大会のキーパーソン。私のモチベーションを感じ取ってくれたのか、最近はらしくもなく AOJ ICPC にある Regional の過去問を埋めまくってくれている。感謝の一言である。最近の UCup や ARC でも考察が光っており、本番での活躍が期待できる。問題文を雑に読んで理解する能力の高さや、sapphire の言うことを理解して解法を言語化する上手さに定評があるので、大いに頼りたい。

sapphire15

最近忙しいのか、連絡を送っても数日は見てくれないこともしばしばあり、消息不明なことが多い。が、それでも UCup には半分以上は出てくれている。実装を任せて良かったと思ったことはほとんどないので、当日は考察に専念していただきたい所存である。

チーム全体として

最近の UCup でも低・中難易度枠の処理速度は向上していて、パフォーマンスの安定感は増してきている。しかし高難易度や高度典型といった部分には弱く、5 時間コンテストで後半 1 時間以上椅子を温めていることも珍しくない。それをふまえて最近は高難易度問題への取り組みを意識的に行っているので、DELIAIR の後半戦に注目いただきたい。

個人的注目チーム

失礼ながら勝手に書かせていただきます。

Speed Star東京大学

今大会国内優勝本命チーム。その名の通りスピードがすごい。特に SSRS 氏の ICPC 適性については言うまでもない。3 対 3 だと正直言って 100 回やって 1 回も勝てる気がしないが、勝てるとしたら noimi が二日酔いで来て負の貢献をするくらいか。

tonosama(東京工業大学

昨年度の横浜優勝チーム(メンバー入れ替えあり)で、国内二強の一角という認識である。特に高度な知識や深い考察が求められる問題に強いという印象がある。つまり強い。アジアセミファイナルの話もあり、Speed Star を倒してほしいという気持ちがないと言えば嘘になる。

The Raspberry Candies(東京大学

DELIAIR の宿敵。メンバー全員のレベルが高く、ややこちらの分が悪いと感じている。特に chinerist が、我々のチームでは到底思いつかないような何かを放ってくることが多い印象がある。最近の UCup や少し前の multiuni では互角に戦えている感もあるが、直近の Ucup ではしっかりと負かされており、やはり今大会に照準を合わせてきているか。tabr 曰く「本番に強い」とのことなので厳しい戦いになることは必至だが、DELIAIR v.s. The Raspberry Candies には是非ご注目いただきたいと思う。

SPJ(東京大学

弊学後輩チーム。ややこちらの分が良いと思っているが、低・中難易度の早解き力やハマったときの最大瞬間風速は著しいので、当然ながら油断ならない強敵である。昨年度の横浜では両者 5 完でレベルの低い争いをしてしまったため今回はより高いレベルで戦いたいと思う一方で、彼らはまだ来年再来年もあるので今年くらいはラストイヤーの老人たちに花を持たせていただきたいと思っております。よろしくお願いいたします。

AMATSUKAZE(東京工業大学

JAG 夏合宿で交流があって以降注目しているが、PG Battle や UCup でも最近の台頭が著しいチーム。メンバー全員とも勉強熱心な印象で、勢いだけでなく実力をつけているのも当然か。我々としてもまだ勝っていたいが、そこそこな確率で負けうるチームとして認知している。

その他

海外 Regional

torisasami と私でベトナム・フエの Regional に出たいという話をして飛行機やホテルも調べていたが、sapphire からの猛反対に遭い泣く泣く断念。一応ベトナムICPC 運営に二人で参加するのは可能かをメールで聞いてみたが、当然不可能と言われて解散。隣の The Raspberry Candies でも tabr と chinerist に意欲があったものの、アジアを下に見ている rniya に反対されたらしい。

赤レンガ倉庫スケート

去年の横浜の日にやっていたので今年もやっていることが期待されたが、開催期間は 12/2 からということで一週間早かった。残念。

ザ・ラーメン屋

今年も行く予定です。

ホテル

9 月に予約したが、近くの通常のホテルはどこも 1 万円以上する感じだったので airbnb で取った怪しさ満点のところに泊まる予定。今年の高さを考えると去年素直にワクチン打ってアパホテル泊まるべきだったと後悔している。

チーム紹介

今年は真面目に用意してきたのでお楽しみに。

意気込み

The Raspberry Candies に勝つ!

まとめ

ラスト ICPC 悔いの残らないよう頑張ります。DELIAIR の応援よろしくお願いします。

第9回 SQLコンテスト (2023/10/13)

第 9 回 SQL コンテストに参加しました。

近況報告

前回の SQL コンテストの後、1 日 1 問ペースで過去問のボス問題を解き、9 月上旬くらいには過去問 40 問全て埋めました。SQL を使って作ってみたいアプリ (?) とかもあるので余裕があったらやってみたいですね。

コンテストの振り返り

問題 1

久しぶりなので少し手惑いました。全てを大文字にするのは UPPER 関数みたいなものがありそうだなと思い、少し調べたら実際に見つかりました。開始約 2 分後に AC。

SELECT
    EMP_CODE AS CODE,
    UPPER(EMP_ENG_NAME) AS ENG_NAME
FROM
    EMP
ORDER BY
    EMP_CODE DESC

問題 2

各人についての最初のログイン日を記録したテーブルを作り、そのテーブル日付が 8 月の部分だけを見ればよいです。開始約 10 分後に AC。

WITH T AS(
    SELECT
        MEMBER_CODE,
        MIN(DATE(LOGIN_DATETIME)) AS MINDATE
    FROM
        ACCESS_LOG
    GROUP BY
        MEMBER_CODE
)
SELECT
    MINDATE AS FIRST_LOGIN,
    COUNT(*) AS MEMBER_CNT
FROM
    T
WHERE
    MINDATE BETWEEN '2023-08-01' AND '2023-08-31'
GROUP BY
    MINDATE
ORDER BY
    FIRST_LOGIN DESC

問題 3

まず最初に 7 月中の最初の受注日をまとめるテーブルを作り、その次に 7 月中の最初の受注日より 1 年以上前の受注日の MAX をまとめた表を作りました。最後に、2 番目に作った表で受注が NULL でない人だけ表示するというコードを書き、開始約 30 分後にサンプルが合ったので出してみますが WA が出ます。その後、なぜ落ちるのかわからずほぼ同じコードを投げてみますが通りません。しばらくして、1 年以上前にも、1 年以上前より後にも両方受注がある場合にバグることに気づきます。受注の MAX を 7 月中の最初の受注日より前に取り、その値が 1 年以上前であるのみ表示するように書き換えることで、開始約 52 分後に AC しました。

WITH T1 AS(
    SELECT
        MIN(ORDER_DATETIME) AS ORDER_DATE,
        MEMBER_CODE AS CODE
    FROM
        EC_ORDERS
    WHERE
        DATE(ORDER_DATETIME) BETWEEN '2023-07-01' AND '2023-07-31'
    GROUP BY
        MEMBER_CODE
),T2 AS(
    SELECT
        MAX(DATE(ORDER_DATETIME)) AS LAST_DATE,
        EC_ORDERS.MEMBER_CODE AS CODE
    FROM
        EC_ORDERS
        INNER JOIN
            T1 ON EC_ORDERS.MEMBER_CODE = T1.CODE 
    WHERE
        ORDER_DATETIME < 
        CASE
            WHEN ORDER_DATE IS NULL THEN '0000-01-01'
            ELSE ORDER_DATE
        END
    GROUP BY
        EC_ORDERS.MEMBER_CODE
)
SELECT
    ORDER_DATE,
    T1.CODE,
    CASE OPTOUT_TYPE
        WHEN 0 THEN ''
        WHEN 1 THEN '不可'
        ELSE '不明'
    END AS OPTOUT
FROM
    T1
    INNER JOIN
        MEMBER_MST ON T1.CODE = MEMBER_MST.MEMBER_CODE,
        T2 ON T1.CODE = T2.CODE
WHERE
    LAST_DATE IS NOT NULL AND DATE(LAST_DATE) < DATE(ORDER_DATE, '-1 year')
ORDER BY
    ORDER_DATE DESC,
    T1.CODE DESC

問題 4

3 問目で時間を浪費してしまったため残り時間はほぼなかったのですが、間に合わなくても良いので見てみます。とりあえず問題文で示されている通りにソートしてから累積和を取ればいいので、表示項目は多いものの 1 つ 1 つは難しくなさそうという印象を受けました。累積和のパートは、計算量的には良くなさそうですが自己外部結合するのが一番頭を使わずに書けるので、その方法を取りました。しばらくしてサンプルが合ったので出してみますが、3 つあるテストケースのうち 1 つだけが通りません。実はデータのある都道府県数が 30 より多いのではないかという疑いを持って投げ直したりしましたが、何をやっても通らないのでとりあえず放置しました。コンテスト開催期間終了後に改めて見てみると、普通に最初のソートの比較がバグっているのに気づき、修正すると通りました。

WITH T1 AS(
    SELECT
        SUM(
            CASE KIND_CODE
                WHEN '100' THEN TOTAL_VALUE
                ELSE 0
            END
        ) AS VAL,
        SUM(
            CASE KIND_CODE
                WHEN '150' THEN TOTAL_VALUE
                ELSE 0
            END
        ) AS CNT,
        RANK() OVER(
            ORDER BY
                SUM(
                    CASE KIND_CODE
                        WHEN '100' THEN TOTAL_VALUE
                        ELSE 0
                    END
                ) DESC,
                SUM(
                    CASE KIND_CODE
                        WHEN '150' THEN TOTAL_VALUE
                        ELSE 0
                    END
                ) ASC,
                PF_CODE ASC
        ) AS RNK
    FROM
        CONVENIENCE
    WHERE
        SURVEY_YEAR = 2019
    GROUP BY
        PF_CODE
), T2 AS(
    SELECT
        SUM(VAL) AS VAL,
        SUM(CNT) AS CNT,
        (RNK + 2) / 3 AS GRP
    FROM
        T1
    GROUP BY
        GRP
    ORDER BY
        GRP ASC
), T3 AS(
    SELECT
        T2.GRP,
        T2.VAL,
        T2.CNT,
        SUM(
            CASE
                WHEN MT2.GRP <= T2.GRP THEN MT2.VAL
                ELSE 0
            END
        ) AS CUMVAL,
        SUM(
            MT2.VAL
        ) AS ALLVAL
    FROM
        T2
        CROSS JOIN
            T2 AS MT2
    GROUP BY
        T2.GRP
)
SELECT
    GRP AS NO,
    VAL AS TTL_SAL,
    ROUND(100.0 * VAL / ALLVAL, 1) AS PER_SAL,
    ROUND(100.0 * CUMVAL / ALLVAL, 1) AS CUM_SAL,
    VAL / CNT AS AVG_SAL
FROM
    T3
WHERE
    NO <= 10
ORDER BY
    NO ASC

結果

52:38(+2) で問題 1,2,3 の 3 完 60 点で、35 位でした。

終結

難易度的には全完できるセットだったとは思います。

感想

SQL コンテストでは自分でサンプルを作ってデバッグするということができないので、サンプルは合うものの通らないという状況の対処がかなり厳しく感じました。ただ、それ以前の問題として、問題文を正しく読むのと正しい論理を構成するのを心掛けたいです。

まとめ

次は全完

JAG 夏合宿 2023 コンテスト編 (2023/09/16-18)

合宿中のチームコンテストの振り返りをします。

チーム構成

ICPC チーム DELIAIR の torisasami, tokusakurai, sapphire15 で出ました。

参加環境

ICPC 本番を想定して、昨年度の ICPC 地区予選に向けて配布された仮想環境を使いました。また、キーボードは本番と全く同じものを torisasami が持ってきてくれたのでそれをノート PC につないで使いました。3 日間ともコンテスト開始前に全てのファイルを削除した状態から始めました。

1 日目

セットは 2022 年の韓国 ICPC 国内予選のセットらしいです。3 時間 11 問。

チーム名は sapphire15 が遊んで DELIAIR(おいしい庄内空港) になりました。

始まると私がまず環境構築をし、2 人にはとりあえず考察を任せました。環境構築では、zip の解凍や cpp ファイルをコンパイルしてサンプルを実行するシェルスクリプトを書き、その後は CLion を使って main.cpp を作ってよく使うテンプレートを書きました。初日で不慣れなこともあって、ここまでで 10 分少しかかりました。

A,C,E は既に読めて解けているようだったので、順に話を聞いて実装しました。まず E 問題は「二分探索でいいね」となって実装します (0:17 AC)。次に、A は torisasami から入力と操作を言われるがままに実装してみると WA が出ます。結論から言うと問題文の読み落としが原因でした。問題文は本番を想定して英語なので、使える錘の重さが "1, 2, 5, 10, 20, 50 and 100 g" と書いてあったのですが、"and" の後に改行が挟まっていたため "100 g" だけ浮いてるのに気づいたときには 声が出てしまいました (0:23 AC)。C は ABC で最近やったことあるくねと思ってたらつい 1 ヶ月前にありました (0:27 AC)

とりあえず序盤の簡単枠を解いたところで、F が実質的に functional graph の最長パスの頂点数を求める問題であることを sapphire15 から聞きます。実装方針は迷ったのですが、最終的にメモ化再帰のような dfs でやりました。 n = 0 という最悪のケースもあったようで、本番はこれに気づいていませんでしたが、幸運にも答えを 0 で初期化していたため特に問題なく通りました (0:41 AC)

私が F を実装している間に二人は G の考察を済ませていたようで、高々 30 手でゲームが終わるので状態数は 30(a+1)(b+1)(c+1) になるのでメモ化再帰で間に合いそうということです。メモリが結構かさみそうなので生配列で十分な長さの配列を確保しておいた方がメモリ節約に効くかと思い、長さ 3\times 10^7 の生配列を用意してみたら、仮想環境のメモリが少ないせいで手元で RE しました。仕方ないので unordered_map を使って実装して、提出すると WA が出ます。0 個の山に対して操作するのを許容する実装をしていたので、そこを修正すると通りました (1:10 AC)

K は torisasami が解けていそうだったので完全に任せることにして私は sapphire15 と J を考えました。同じ x 座標の点の個数で平方分割というアイデアが出て、大と大、大と小の組み合わせは簡単にできそうです。残る小と小は苦戦しましたが、sapphire15 が反対の座標に注目するといういいアイデアを思いついて解決します。toriasami は K でペナを出していたので、一旦コードを印刷してもらってその間に J の実装を進めました。

J の実装で苦しんでいると torisasami が K の修正ができるようだったので、交代してやってもらうと通ります (1:36 AC)。J もあともう少しというところだったので、\log n を余計につけてしまった気がしますが、制約が小さいこともあってか無事に通ります (1:45 AC)

残っている問題で通されている問題が B のみだったので、torisasami に B を読んでもらっていたのですが、難読で正しく理解できているか怪しいということを聞きました。一緒に一行ずつ読み進めていきます。彼は挿入した後のものに対して編集操作をできるのかどうかがわからなかったようですが、さすがにそんな訳はありません。それはなしという方向性で考えると、 T の長さ 2M 以下の全文字列について T との編集距離がわかれば DP できるのがわかったのですが、これは愚直にやると O(NM^3) 時間かかるところ始点を固定することで O(NM^2) でできます。その後は edit distance のライブラリを写経して無事 AC できました (2:21 AC)

残るは AC なしの D,H,I 問題で、その中でも H は明らかにグロそうだったので見なかったことにして sapphire15 が D を、torisasami と私が I を考えました。I は良さそうな DP を思いついた気がして時間もなかったので適当に書き始めていたのですが、書いているうちに普通に 2 乗じゃんとなって終了しました。sapphire15 は D の良さげな方針を思いついていたようですが、どう実装に起こすのかを思い描くことができませんでした。

day1 最終結果 (tatyam さんの \mathbb{X} より)

終結果は 8 完で 3 位でした。解説を聞いても残りの問題は時間内に解くのは相当厳しそうな感じだったので、解けるべきところはきちんと解けたのが良かったかなと思います。一方でソロ参加の SSRS さんにはスピードで圧倒的敗北を喫し、速すぎて度肝を抜かれました。

2 日目

この日は合宿参加者の有志セットらしいです。5 時間 12 問。

チーム名は torisasami が着ていた加茂水族館の T シャツから、その別名を取って DELIAIR(クラゲドリーム館) になりました。

例によって環境構築から始まります。1 日目をふまえ、問題ごとに zip を解凍するのが面倒だったので、最初に全問題の zip をダウンロードしてからシェルスクリプトの for 文で全部一括で解凍するようにしました。

この日の序盤簡単枠は A と C のようです。A は torisasami に出された式を言われるがままに書くとちょうど答えが 1 ずれていて、実際ずれる原因もわかっていそうだったので答えから 1 を引くと通りました (0:19 AC)。続く C は sapphire15 から言われた式をそのまま書いたら通りました (0:22 AC)。

sapphire15 は鋭いことにこの時点で K に目をつけていました。話を聞くと、各頂点への直前の頂点で場合分けした上位 2 個の最短パスがあれば良さそうと思って書いてみますが、(a_i,b_i) が distinct 出ない場合に壊れることがあるのに気づき、一旦パスしました。

その間に torisasami が H の考察を済ませていて、式が降ってきたのでそれを実装することになりました。式に二項係数が入っていたので、まず階乗とその逆元テーブルを作ります。こんなんソラで書けるやろとソラ書きした modpow を少しバグらせてしまいましたが、何とか合わせます (0:49 AC)。K 問題も補グラフ bfs の要領でやればいいことに気づいたので、苦しみながらも実装すると通ります (1:13 AC)。

実装していた間に二人は B,D,E,F あたりを見ていました。mod 998244353 の数え上げがかなり多そうだったので、この辺で sapphire15 に modint のライブラリの写経をやってもらいました。torisasami は B は頑張れば行けそうという雰囲気を出していたので、私はそちらは任せて通されている F を行きました。F の初見の印象は、差分の和を「山を作ったときに、それを高さ 1 の長方形何個で作れるか」の答えに置き換えるのでは?というものでしたが、その方針で考えてもどうにもなりません。一方で、B を書いている torisasami は最後のサンプルだけ合わなくてなんで?と言っていました。印刷したコードをみて、私が「perm(n,k)k\lt 0 のとき大丈夫?」と聞いてみると「それだ!」となって通ります (2:05 AC)。torisasami と協力して今度は F を括弧列に対応させて考えてみることにしました。この筋自体は良かったのですが、その後は解けたと思ったら嘘だったり、鏡像法に帰着できるかという観点でウンウンと考えていても進まなかったり、結局 1 時間以上はこの問題を考えたのですが解けずじまいになりました。

L 問題は sapphire15 から一般グラフの最大重みマッチングがあれば解けるという声が出ていましたが、持っておらず、さすがに別の賢い方法があるんだろうということでパスしました (解説で想定解が最大重みマッチングだと聞いてひっくり返りました)。I も見ましたが、そもそも 1 クエリでもわからないのでパスします。

sapphire15 は D,E に取り組んでいて、ジムニーツリーという共通概念が出てくるようなのでその定義を聞いてました。ジムニーツリーであるためには、片方の色の個数がある部分木のサイズになっていれば良さそうです。とりあえず問題の条件を満たすための必要条件を二人で考えて、「これか?」「やっぱ違うか?」を繰り返していました。途中で sapphire15 が必要十分条件を思いついたのですが、必要性・十分性ともに自明ではないように思えたので、納得できるまでかなり議論をしてもらいました。開始 3 時間過ぎくらいになんとか証明が完成したものの、それを実装する方法が見えません。オイラーツアーや BIT などを使えばできそうなのはわかったのですが、実装をやりたくなさすぎて「この必要条件ほんとにあってるの?」という気持ちになってもう一回考えたりしたのですが、やはり合っていて時間をロスしました。仕方ないので実装をします。一時間くらいやってようやくサンプルがあったので出してみるとなんと通ります (4:37 AC)。

torisasami と sapphire15 は J をやっていて、PC が空いてる間に少しずつ実験を進めていた結果、偶数のときの勝敗がわかっていて、奇数のときはどうかという感じになっていました。実験コードがバグっていたようで、直してみると縦横両方奇数のときも (H,W) = (3,3), (3,5) のとき以外は規則性があることがわかり、時間もないのでこれしかないだろということでそこだけ場合分けしたコードを出します。 WA で「さすがにだめかー」と落胆します。一応コードを印刷してもらって確認していると、torisasami のコードは縦横の長さでの場合分けが if (h > y) になっていたので、私が「これ if (h > w) じゃないの?」と言うと「そうじゃん!」となって出します。AC で爆笑が起こりました (4:58 AC)。torisasami 曰く、「人生で一番科学の力を感じた」そうです。

day2 最終結果 (tatyam さんの \mathbb{X} より)

終結果は 7 完で 4 位でした。最後に 2 問通して追い上げましたが、中盤の空白が長すぎてだめでした。特に F 問題はラグランジュの反転公式を使うようで、この公式自体は知っていたものの実戦で使えるレベルには習得できていないということなので、自分の未熟さを感じました。SSRS さんは F を実験エスパーで式を見つけたと仰っていたのですが、そんなことができるのかと俄かに信じがたかったです。あとは実装力が課題で、E を実装する時間が長すぎたのと、解法までは見えていた D に取り組む時間がなかったのが悔やまれます。

コンテスト後は 9 完して調子に乗った The Raspberry Candies の tabr が煽りに来て、ここまで 1 勝 1 敗なので明日負けた方の atcoder ユーザーネームを勝った方が自由に変えよう (loser1, loser2, loser3 など) みたいな話が上がりました。

3 日目

最終日は JAG のオリジナルセットらしいです。5 時間 11 問。

ここまでチーム名を毎日変えていて、最終日のチーム名で迷っていました。2 日目の夕食のときに torisasami から「鶴岡市ユネスコ食文化創造都市に登録されている」という話を聞いて DELIAIR(ユネスコ食文化創造都市) に決まりました。

いつも通り環境構築から始まりますが、3 日目なのでそこそこ慣れてきました。

前から問題を見て行った torisasami は A が解けているらしいので実装を任せたら通っていました (0:11 AC)。その間に sapphire15 から B,J の話を聞き、どちらもできそうなので実装を始めます。B は頂点倍加して bfs をするだけなのですぐ通ります (0:22 AC)。J はあまり細かいところを詰めずに単純な for 文の dp の実装を始めました。しかしながら途中で閉路ができることに気づいて 01bfs で実装し直しになり、だいぶ時間をロスしてしまいました (0:47 AC)

ここからは mod 998244353 の数え上げが複数目に入ったのでとりあえず sapphire15 に modint を写経をしてもらいました。E は確率の累積積を使って計算できるという話を torisasami から聞いて実装をしたもののサンプルが合わないので頭を抱えますが、余事象の確率を求めていたことに気づき事なきを得ます (1:11 AC)。

I は torisasami と一緒に考えていたもののわからずに苦労しましたが、torisasami が priority queue で保留しておくやつであることに気づいて通します (1:22 AC)。チームメンバー全員この手の問題が苦手な気がします。

残っている問題で一番解けそうな問題は C で、余事象で立式は出来ていてあとは高速化するだけです。畳み込みを使って計算できそうなものの意外とできず、数十分考えてようやく分割統治でできそうなことがわかりました。sapphire15 にはとりあえず畳み込みは必要になりそうなので前もって書き始めてもらっていたので少しだけ時間を節約できましたが、ライブラリ写経で結構ミスっていたので結局トントンだったかもしれません。分割統治の実装でも結構血迷ってしまって通すまでにだいぶ時間がかかってしまいました (2:48 AC)。

torisasami と sapphire15 は D 問題を考えていて、解けている雰囲気を出していたので torisasami に実装を任せるもサンプルが合いません。この時に sapphire15 が考察漏れに気づいて出直しになります。

K 問題は sapphire15 が辺の削除ができる UF (オフラインダイコネ) があればできると言っていたのですが、「不勉強のため持っておらずすみません」という形になりました。後でオフラインダイコネを勉強してみると、自力で再発明できそうな範囲だったのでライブラリを持ってないからと切り捨てるには惜しい問題だったかもしれません。

H 問題も考えていて、文字列 t_i の長さが全部 1 ならば trie 木でできそうというところから始まり、t_i の長さで平方分割する方法で考えます。長さが長いものについては個別にダブリングすれば良さそうと torisasami が言うので、確かにと思って実装を始めます。しかし、実装を始めてからこの方法が全くの嘘であることに気づき、torisasami に話をするとやはりだめという結論になって、隣の SPJ がたくさん通してウハウハしているのを横目にかなり萎えました。なんとか sapphire15 が t_i+s_1+\cdots+s_n に対して z-algorithm を使う解決策を思いついて一応できることがわかりました。そこからは実装を頑張るだけで、メモリも計算量もかなりカツカツで正直 2.5 s に間に合う気がしなかったのですが、何とか一発 AC できた時は本当にほっとしました (4:16 AC)。解説で TL がもし 2 s だったら落ちていたチームが 1 つあったという話があったのですが、おそらく DELIAIR だと思います (調整ありがとうございます)。

torisasami と sapphire15 は D の修正案が見えているようで、全方位木 DP でできるとのことです。全方位木 dp のライブラリを写経してもらったのですが、変に抽象化してあるものを使うよりは直に書いてしまった方が良かったかもしれません。写経にもそこそこ時間がかかり、ようやく取り掛かってみるとサンプルが合いません。どうも torisasami が普段使っているライブラリと私が用意してきたものの使い方が大きく違うらしく、そこで揉めているうちにコンテストが終了しました。この件に関しては後日 torisasami の方が勘違いしていたということで解決しました。

day3 最終結果 (tatyam さんの \mathbb{X} より)

終結果は 7 完で 6 位でした。SPJ に 9 完で優勝されてかなり残念でした。その他にも SSRS さんソロの Speed Star に 3 日間で全敗し、The Raspberry Candies にも最後 K を通されて負け越しするなど、3 日間で一番厳しい結果になりました。解説を聞いてみても通した問題も方針が悪かったりしたので、方針も含めた実装力不足を痛感しました。

さすがに atcoder のユーザー名を変えるのはやばいので 10 月の東京工業大学プログラミングコンテストのチーム名を自由に決められるということになりました。DELIAIR のチーム名をお楽しみに。

まとめ

最近競プロから気持ちが離れていたので、モチベーション復活のいいきっかけになりました。横浜では善戦できるように精進します。

JAG 夏合宿 2023 生活編 (2023/09/16-18)

ICPC OB/OG の会主催の夏合宿に参加しました。

まえがき

この記事では合宿のチームコンテスト以外の部分について主に書きます。びっくりすることにカメラロールを見返したらオリセンで撮った写真が 1 枚もなかったのでほとんど文章になりますがご容赦ください。

スケジュール

合宿は 9/16 (土) から 9/18 (月・祝) の 3 日間で、東京都渋谷区にある国立オリンピック記念青少年総合センターで行われました。以下は実際ベースのスケジュールです。

9/16 (土)

時間 内容
12:00 -- 13:00 現地集合
13:00 -- 14:00 合宿ガイダンス・自己紹介・コンテスト準備
14:00 -- 17:00 コンテスト (3h)
17:00 -- 17:30 解説 1
17:30 --18:30 夕食
18:30 --19:00 解説 2
19:00 -- チェックイン後自由時間

9/17 (日)

時間 内容
07:30 -- 08:30 朝食
08:30 -- 09:00 コンテスト会場集合
09:00 -- 10:00 コンテスト準備
10:00 -- 15:00 コンテスト (5h)
15:00 -- 16:30 解説
17:30 --18:30 夕食
18:30 -- 自由時間

9/18 (月・祝)

時間 内容
07:30 -- 08:30 朝食
08:30 -- 08:45 チェックアウト・シーツなど回収
08:45 -- 09:00 コンテスト会場集合
09:00 -- 09:45 コンテスト準備
09:45 -- 14:45 コンテスト (5h)
14:45 -- 16:00 解説
16:00 現地解散

持って行ったもの

  • パソコン、充電器、マウス
  • スマホ、充電器
  • コンセントタップ
  • 蟻本、競プロ関連のメモを書いてあるノート、印刷したライブラリ
  • バスタオル、小さいタオル
  • 歯ブラシ、髭剃り
  • ティッシュ、マスク
  • 2 日分の着替え
  • 折り畳み傘
  • 将棋盤駒

持って来なかったことを後悔したものは歯磨き用のコップくらいです。

1 日目

前日までインターンで毎日 8 時間・週 5・全出社の労働を 3 週間行っていたので、気づいたら当日になっていました。最初から疲労度 MAX の状態で合宿が始まります。

現地集合まで

荷造りを終えて 10 時過ぎに家を出ます。Kite_kuma さん、miscalc さん、naniwazu さん、かっつさんなど、合宿参加者に誰かしら将棋プレイヤーはいて、なおかつ誰も将棋を持って来ないだろうという読みで千駄ヶ谷にある日本将棋連盟に寄って将棋盤駒(合わせて約 3,000 円)を買いました。

購入した将棋盤と駒。プラスチック 1 字駒の物珍しさに惹かれて即決

その後は 11 時に新宿で torisasami くんと待ち合わせて食事する約束をしていたのですが、いつも通り torisasami くんが遅刻するという連絡をしてきたので新宿駅まで歩いて向かいます。パソコン、蟻本、ノート、ライブラリなどで荷物は想像以上に重く、駅に着いた頃には既に体がバキバキになっていました。重い荷物を降ろして休憩している間に torisasami くんが来て、みやざき館で食事をしたのち小田急線で会場のオリンピックセンターに向かいました。オリンピックセンターは中高の部活の合宿で毎年来ていたので、懐かしさや昔との変化を感じながら会場に着きます。

ガイダンス

会場に着くと、まず紙の宿泊のしおりをもらいました。こちらには事前にメールでもらっていたしおりとは違って、各部屋の参加者の名簿が載っていたので、自分の同室を見たり知り合いのいる部屋を眺めたりしていました。自己紹介では将棋盤駒を買ってきた話をしたらそこそこ笑いが起きて、その後に続く人たちも将棋に絡めた話をされていたので嬉しかったです。

コンテスト

チーム名 DELIAIR(おいしい庄内空港)
時間 180 分
問題数 11
正解数 8
順位 3
VS. Speed Star X
VS. The Raspberry Candies O
VS. SPJ O

夕食

この日はチームメイトの 3 人に加えてかっつさんと合流して一緒に行きます。場所はセンター内の食堂カフェテリアふじで、17 時半過ぎに行ったところかなり混んでいて入れるまでに 10 分ちょっとかかりました。かっつさんとは社会の話や石川の話をしました。私は 3 週間のインターンでへばりながら合宿に参加していたので、社会人をやりながら深夜の Codeforces に参加し、休日に石川から東京まできて運営の仕事をしているかっつさんの無尽蔵な体力に凄まじさを感じました。

食事はいわゆる合宿飯みたいな感じです。昔は選択肢がいくつかあったと記憶していたので、問答無用で同じメニューになっていて少し驚きました。食事中は torisasami くんが「ICPC は提出するたびに 3 km 先の提出所まで走って出しに行く方が盛り上がるんじゃね」とか「コードファーマー」がなんとかといつも通りの意味不明トークを繰り広げていて安心感がありました。

チェックイン

再びコンテスト会場に戻って解説が終わった後は、荷物をもって部屋に向かいます。部屋に着くとルームメイトは既に全員揃っていて、簡単に自己紹介をしました。以下、失礼ながらルームメイトについて少し紹介させていただきます。

ebi_fly さん

東京工業大学チーム AMATSUKAZE 所属。noya2 さんが何度か部屋に来たり、東工大メンバーでコンテストの感想戦や TTPC 作問の通話を深夜までやっていた話を聞いて、東工大は学年を越えての交流が盛んで羨ましく思いました。

ebi_fly さんの参加記

nisshy_280 さん

滋賀大学チーム coconut milk 所属。合宿直前まで北海道でバイトしていた話がとても面白かったです。私も親戚の家が滋賀にあって定期的に行っているので、滋賀県トークを興味深く聞いていました。

krps さん

早稲田大学チーム hot-k-k-1 所属。B1 ということで、22 歳大学院生にとっては若すぎて眩しすぎます。早稲田の競プロ事情も少し聞けて良かったです。今後の活躍を楽しみにしています。

部屋は階段や奥にある談話室のすぐそこという非常に良い立地でありながら、片方の照明があまりにチカチカしていて使い物にならなかったのが難点でした。

自由時間

自己紹介の後は同室の 4 人で一緒に風呂に行きました。風呂ではシャンプーのポンプの押す部分が破壊されいて真下に液が垂れてくる、シャワーの散水版が外れていて水がバシャバシャ出てくるなど、これまた難物に事欠きません。学部生の nisshy_280 さんや krps さんに、B1 B2 の頃から横浜出られるのはいいですねとついうっかり老人トークをしてしまいました。

風呂から上がるともう 20 時半を回っていて、各自で ABC 320 の参加準備を始めます。Wi-Fi の存在を知らなかったので、全員テザリングを使って参加することになりました。他の人と同じ部屋で atcoder コンテストに出るのは初めてだったので、情報共有などが起きないよう最大限に注意を払いながらの参加で、普段にはない特有の緊張感がありました。

風呂上がりで疲れがどっときて、眠さがピークに達している状態で ABC が始まります。C が少しめんどかったものの A から E まではあまり詰まらずに解け、F も大まかな解法はすぐわかりましたが細かいところを詰めるのに苦労しました。残る G は判定問題を最大流問題に帰着できることはすぐにわかりましたが、計算量を落とす部分で詰まります。このあたりで無意識に唸っていたようで、後にルームメイトから指摘されました(ごめんなさい)。結局前回の universal cup でやった手法で O(N^3) になりそうなことがわかったので、重い腰を上げて実装を始めます。終了 1 分前にやっとこさサンプルが合ったので出してみるとまさかの TLE で、実はフローを流すかどうかを見る部分で O(N^2M) かかっていました。ABC が 7 問体制になって問題数が減ったにもかかわらず 2 連続で全完に失敗し、心も体もクタクタになりました。

ABC 終了後は krps さんが C で詰まっていたことを知りました。3M の 3 重ループを回すのが実装楽そうと言ったもののあまりピンと来てないようだったのですが、一度止めたリールを再開できると勘違いしていたみたいでした。

ABC 終了後に Kite_kuma くんから将棋をやらないかという打診が discord に来ていたのに気づき、温めていた盤駒をもって談話室に向かいます。Kite_kuma くんはチェスをかなりやっているようで、iPad に対局時計が入っていたのでとりあえず 5 分 5 秒のフィッシャーでやりました。私はクマーという名前からてっきり振り穴党なのかと思っていたのですが 2 手目 8 四歩で早々に意表を突かれます。戦型は相掛かりになり、中盤で私が竜を作ることに成功して有利になるも、うまく食いつかれて受けに回るものの攻めをつながれる展開に。終盤は角 2 枚をベタベタ打ち付けて怪しく迫っていたところ、詰めろになっていないこちらの手を受けてもらってなんとか逆転に成功しました。感想戦でも手抜きで攻め合われてたらやはり負けだったようです。2 局目は時間がなかったので 3 分 2 秒のフィッシャーで戦型は矢倉に。中盤で私が銀矢倉に堅く囲って右辺で飛角金桂歩で手を作る理想的な展開になりました。途中で Kite_kuma くんの時間が切れてしまい、その後は適当に指し継いでいたのですが、私が飛金両取りをうっかりするやらかしをしてしまい、談話室撤収の 0 時も近かったのでお開きになりました。

部屋に戻ると krps さんは既に熟睡されていて、他のルームメイトは誰もいませんでした。その後、帰ってきた nisshy_280 さんが ABC で水色になったことを聞きました(おめでとうございます!)。さすがに疲れていたので 0 時半頃に寝床に就きました。

2 日目

朝 7 時 20 分頃に (おそらく方向的に) ebi_fly さんのアラームの音で起床します。正確には眠りが浅かったゆえ途中 4 時、6 時あたりに 2 回ほど目が覚めてしまったので 3 回目の起床となります。

朝食

軽い洗顔などを済ませて、7 時半前後にルームメイト 4 人で行きました。会場はやはりカフェテリアふじです。朝食は最初にご飯やみそ汁をもらって、そこからはバイキング形式となるのですが、バイキングの部分は急に終わるので選んでいるとほとんど取れずに終わります。前から貪欲に取りましょう。

食事をしていたら torisasami くんの部屋の一行も来て合流しました。torisasami くんはこの日は地元の加茂水族館の T シャツを着て来ていて、「合宿は競技プログラマーしかいないからどんな服着てっても大丈夫だと思ったら違う人たくさんいてビビってる」とか言ってました。

部屋に戻ると、もう片方の照明もチカチカするようになっていましたが、その代わりに入口にある壁灯のスイッチを押せば壁灯が使えるようになることがわかったのでトントンといったところでしょうか。

時間が少しあったので昨日の ABC-G が賢いよねみたいな話をして upsolve しました。しおりには 9:00 -- 10:00 は準備と書いてあったので 10 時に開始できるようにすればいいかと思っていて、コンビニで水や食料を買って 9 時半頃にコンテスト会場に着いたのですが、どうやら 9 時集合であったようで、チームメンバー・JAG スタッフの方々には大変ご迷惑をおかけしてしまい、申し訳ありませんでした。

コンテスト

チーム名 DELIAIR(クラゲドリーム館)
時間 300 分
問題数 12
正解数 7
順位 4
VS. Speed Star X
VS. The Raspberry Candies X
VS. SPJ O

夕食

部屋に戻ると nisshy_280 さんと krps さんしかいなくて、少し待っても ebi_fly さんが帰って来ないので、貴重品は持って鍵を開けっ放しにして 3 人で行くことになりました。夕食会場で ebi_fly さんが前にいるのが見えて、「鍵開けっ放しじゃん笑」となりました。貴重品は常に持ち歩きましょう。会場では奇遇にもまた torisasami くんの同室一行と一緒になりました。このときの彼の意味不明トークは思い出せませんが、食事会場を出る時に「なんか腹一杯なんだけどなんでだろう」とボケていて、nisshy_280 さんにツッコまれていたのが面白かったです。

tabr くんから夕食の画像をもらいました。感謝!

自由時間

この日もまた同室の 4 人で風呂に行きました。風呂では nisshy_280 さんのバイトの話を聞いてたら、どうやら私も昔そのバイト先に行ったことがあるということがわかって少し盛り上がりました。帰って ARC165 の準備をしようとしたとき、充電器をコンテストの部屋に忘れたことに気づきましたが、まあ今 95% あるので耐えるだろうということでわざわざ取りに戻りにはいきませんでした。

部屋では ARC に向けて仮眠を取る流れになっていたので、私もそれに便乗して横になりました。連日重い荷物を運んでいるせいか、足がプルプル震えているのを感じてさすがに休憩取らないとなと思い、30 分程寝ました。

起きた後は tabr くんの部屋にお邪魔して、potato167 さん、pitsu さんと一緒に大富豪に入れてもらいました(いきなりなのに本当にありがとうございます)。特殊ルールは 8 切りと J バックのみで、なかなか地味な戦いでしたが、革命がたくさん起きて面白かったです(革命起きてる!)。途中から houren さんも戻ってきて、5 人でやりました。計 7,8 戦はやったでしょうか、229 室の皆様本当にありがとうございました!

時刻は 21 時手前になっていたので、談話室で Writer の chinerist さんと少し話をした後部屋に戻って ARC の準備を始めます。触っていないはずの PC の充電が 62% になっていたので、さすがにびっくりしてとりあえず低電力モードをオンにして画面の明るさを最低にする応急処置を取りましたが、2 時間は持たないだろうなと思いました。

今日は仮眠を取ったおかげか少しすっきりした状態で ARC が始まります。A は素べきに分解するのが最小だろうと思ってやってみると通ります。B は最初は降順ソートだと誤読して、さすがに 600 点にしては簡単かと思って確認したら昇順であることに気づきます。基本的に一番後ろをソートするのが良くて、それをどれだけ前にできるかという話になるので、ごちゃごちゃやって 1 ペナで通します。C は見てすぐに解けました。D を見て不可能か?となり、E を見るとこちらもまた不可能か?となって結局どちらかというと可能そうな D に戻ってきます。各頂点から各頂点への到達可能性を持ちつつ辺の追加ができれば良くて、これは bitset を使う O(N^3) でできるのを思い出し、TL ギリギリかなと思いながら書いてみると 43 ms で AC します。続く E では、10 分くらい考えて順列を考えるのを思いつき、2 乗の木 DP で O(N^3) だなあと思って意気揚々と実装すると合いません。よく考えると情報が足りないのに気づき、DP の状態を追加して O(N^5) になってしまいましたが、定数倍は良さそうなので書いてみると 816 ms で AC します。残りは 10 分だったので、F 問題を考えながら今のうちにと歯磨きを済ませておきました。最終結果は A-E の 5 完 31 位で、unrated ながらも悪くない結果を残せて安心しました。充電もなんとか最後まで持ち堪えました。

ARC が終わると、同室で参加されていた ebi_fly さん、krps さんはどちらも B の WA で苦しんでいたようで、特に ebi_fly さんは 1 ケースのみ WA だったようです。ebi_fly さんのコードを少し説明してもらいながらデバッグを手伝っていると、for 文の範囲が間違っていそうだったのでそれを直してもらうと通りました。

その後は例によって将棋をもって談話室に行くと、Kite_kuma くんがいたので将棋をやります。戦型は角換わりになり、相腰掛銀だと思って適当に指し進めていたら相手の銀がいつの間にか 6 四まで来ていたので急いで右玉に組み替えます。8 筋で銀交換が行われた後 7 八の金取りに打たれた 8 七銀を秒に追われて手抜いたのが良くなく、駒損で切れ模様という苦しい展開になります。苦しいながらも戦線を拡大しながら迫っているといつの間にか角が手に入って、角のラインだけで手になる形になってなんとか勝利しました。次はその場にいた miscalc さんと Kite_kuma くんでやってもらい、その間に私は ARC Writer の chinerist さんから D・E の想定解を聞きましたが、私の解法とはいずれもかなり異なっていそうだったので勉強になりました。tabr くんが、わざわざ家に帰ったにもかかわらず冷えているチームメイトのレーティングを見てほくそ笑んでいたのも印象に残っています。

部屋に戻ると今度は krps さんが B のデバッグをしていました。添え字が 1 個ずれていそうだったので、その辺を直しつつやってもらうと通って良かったです。B は実装込みで結構難しいと思ったので 1000 人も解かれているのは atcoder 参加者のレベルの高さを感じました。

同室で過ごす時間も最後なので、気になることあればなんでも聞いてくださいという感じで打診してみたら、「やった精進」や「黄色から橙になるためには」という話題が上がったので、それについて少し喋りました。少しでも参考になっていれば幸いです。その他にも universal cup などの話をしていたら 1 時を回っていたのでこの辺で就寝しました。

3 日目

3 日間の合宿もあっという間に最終日。この日はチェックアウトの準備のため、余裕を持って 7 時頃に起床します。起きたらとりあえず顔を洗ってからシーツと枕カバーを畳み、散らかしっぱなしの荷物を整理して、JAG スタッフの方にシーツと枕カバーを返却してから食事に行きました。

朝食

この日は ebi_fly さんのチームメイトの noya2 さん、shobonvip さんと合流しました。noya2 さんが前日の ARC-B が全然嘘なのに通ったという話をされていて、確かになんでマルチテストケースじゃないんだろうということを言ったら、\mathbb{X} で強い人達のマルチテストケースのお気持ち表明が飛び交ってるという話を聞きました。その後 noya2 さんと少し話したのですが、私が PCT さんと Nyaan さんの yukicoder 数え上げコンテストのテスターとして認知されているらしくかなり驚きました。今後は writer とかもできるように頑張ります。

朝食から戻った後は部屋にある小さいテレビを始めてつけてみたりして少しゆっくりした後、部屋の鍵を返却して 9 時に間に合うようにコンテスト会場に向かいました。

コンテスト

チーム名 DELIAIR(ユネスコ食文化創造都市)
時間 300 分
問題数 11
正解数 7
順位 6
VS. Speed Star X
VS. The Raspberry Candies X
VS. SPJ X

現地解散後

かっつさんや東大メンバーと少し喋った後、疲れていたので参宮橋駅から真っ直ぐ帰りました。torisasami くんはインターンの面接で失言をして説教されたもののなんか受かったという話をしていました。新宿でほとんどの人と別れた後は Kite_kuma くんと一緒になり、今年の卒論配属が演習の成績で決められているとかいう割と意味不明な話を聞いてびっくりしました。人と話している間は良かったのですが、一人になると急に疲れがこみ上げてきて電車内でもかなり具合が悪くなりましたが、なんとか無事に帰宅できました。

謝辞

JAG スタッフの皆様へ

合宿を開催していただきありがとうございました。私自身 1 参加者として非常に楽しく充実した 3 日間を過ごせました。コンテストに出てきた問題の質・量・解説、運営など、どれをとっても JAG の皆様の並々ならぬ労力の上に成り立っていることが感じられました。2 日目の集合に遅刻したり、コンセントを抜き忘れたりとご迷惑をおかけしてしまったのを反省しています。今後ともよろしくお願いします。

チームメイトへ

急な誘いにも応じてくれてありがとうございました。今回の合宿で DELIAIR の弱い部分がかなりわかったと思うので、また練習しましょう。

ルームメイトへ

合宿期間中は一緒に行動する機会が多くてとても楽しかったです。特に、torisasami と私の意味不明な話も嫌な顔せず聞いてもらって感謝しています。

将棋関係者の皆様へ

将棋ができる競技プログラマーが意外と多くてびっくりしました。これからもオンサイトの機会があれば将棋を持っていこうかと思っています。かっつさんと miscalc さんは次の機会があればぜひよろしくお願いします。

参加者の皆様へ

仲良くしていただきありがとうございました!

まとめ

さすがに疲れた。