8
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【AtCoder色変記事】入緑したので、やってきたことを振り返る

8
Posted at

はじめに

初めまして, KKと申します. 2026/2/28のAtcoder Begginer Contestにて無事緑コーダーになることができたので, 私がこれまでやってきたことを記事にします. 少しでも灰, 茶コーダーさんの参考になれば幸いです.

スクリーンショット 2026-02-28 231958.png

自己紹介

 プログラミングは完全に大学から始めています. 大学の授業でプログラミングやアルゴリズムについて学ぶ機会がありました. また, 大学のサークルでWebアプリケーションの開発, Webサイトの作成(言語はPHP, TypeScriptが主)に携わっていました.
 競プロを始めるにあたり, しばしば数学力が指標とされがちです. 私は理系なので当時の数Ⅲまで履修しています. 共通テストは1A, 2Bともに9割超程度, 阪大の二次数学に関しては4割程度:cry:の能力です.

時系列

Atcoderとの出会い~入茶(2024年12月~2025年5月)

 AtCoderを始めたきっかけは大学の友人複数人のすすめでした. アカウントを作成してまずAPG4b (https://atcoder.jp/contests/APG4b) をやりました.
 言語選択については特に理由がなければC++かPythonと言われています. 私は大学でC言語の授業を履修していたこと, Python(というか動的型付け言語)に若干苦手意識があることを理由にC++を選びました(RustやC#を使われている方もいます). APG4bは2日で2章までを終わらせました.
 C++の基本的な文法を学んだ後はひたすらABCに出続けました. このときは2完or3完をしてC問題の復習をしていました. 大学の勉強のおかげかあまり入茶に苦戦はしませんでした.

スクリーンショット 2026-03-02 153519.png

茶色停滞期間(2025年5月~2026年1月)

 この期間では9ヶ月でレートが143しか上がっていません. この時は

  • ひたすらABCに参加する
  • 解けなかったC問題, D問題を復習する
  • 過去問のC問題で精進する
  • 余裕があればADT (https://atcoder.jp/contests/adt_top) に参加する

をしていました. 一見問題のない精進方法に見えるかもしれませんが, 知識をあまり身につけられておらず, レートを停滞させてしまいました. 結果として, 9~12月は(学業やサークルの影響もあり)AtCoderから離れていました.

停滞脱出~入緑(2026年1~2月)

 学業が落ち着いてきたので, 前々からやってみたかった精進方法を取り入れました. また, これで伸びなかったらAtCoderを辞めようとも思っていました. それは

です. 鉄則は実際に本を購入して,

  • DPの後半
  • 二ム, Grundy数
  • ヒューリスティック
  • ダブリング
  • フロー

に関しては飛ばして, これら以外を解きました. これを書いている時点でも二ム, Grundy数, フロー, ヒューリスティックに関しては触れていません. また典型90問は☆2~☆5の一部をやりました.

 これは勉強全体に関する個人的な意見ですが量の上に質が成り立つと思っています. 今までの私には圧倒的に精進量が足りていませんでした.
 これらの精進で競プロに対する解像度がぐっと上がったような感覚がありました.
 以下, 入緑時のProblems上のデータです.

スクリーンショット 2026-03-02 170842.png

スクリーンショット 2026-03-02 170859.png

スクリーンショット 2026-03-02 171826.png

スクリーンショット 2026-03-02 170918.png
↑ 2026年1~2月の圧倒的精進量が見て取れると思います.

競プロ関連のコンテンツ

 以下では私が触れてきた競プロまわりのコンテンツについて紹介します.

AtCoder Problems(https://kenkoooo.com/atcoder/) とAtCoder Novisteps (https://atcoder-novisteps.vercel.app)

 ProblemsはAtCoderの問題が一覧で見られて, どの問題をACしたことがあるかやこれまでのAC数ヒートマップなどを見ることができます. 問題の難易度も一目で確認できるため, 多くの人が重宝しているサイトだと思います.
 Novistepsは「けんちょんさん」が運営しているAtCoderの問題をジャンル, 難易度別に分けた問題集です. Problemsとの違いとしては問題の難易度を使用するアルゴリズム別に人力で判定しているため, 機械的に難易度を設定するProblemsより指標として確かです.

X(旧Twitter)

 つよつよコーダーはXに集まります. コンテスト後に#ABCxxxで検索するとたくさんの人が感想をつぶやいていて面白いです. また自分が苦戦している問題を張り付けてつぶやけば強い人が助けてくれることがあるかもしれません. 特に周囲に競プロを一緒にやる友達がいない場合は特におすすめです.
 コンテスト直前には皆が「ぞいぞいしてきた」とつぶやく伝統の習慣もあります.

スクリーンショット 2026-03-02 160737.png
(https://youtu.be/qZt3BbQV3nQ?si=uM5mDT1BG1y7j3hq) より引用

Youtube

 Youtubeには競プロの実況動画を投稿している方がいます. 以下私のおすすめを紹介します.

岩井星人 (https://www.youtube.com/@yiwiy9) さん

 上に張った画像が岩井星人です. 緑コーダー(2026年3月時点)で, 特にAtCoderの社長のモノマネが面白かったり, 問題設定へのツッコミが面白かったりします. 「緑コーダーあるある」の動画も見てほしいです.

こたつがめ (https://www.youtube.com/@kotatsugame) さん

 赤コーダーでVimmerの方です. 解くスピードが尋常じゃないくらい速くて見てるだけで面白いです. 動画の後半では解説もしてくれるので, 上級者の思考を知りたい方にはおすすめです.

公式解説 (https://www.youtube.com/@AtCoderLive)

 AtCoderの公式Youtubeチャンネルです. コンテストの後の解説をsnukeさんがしてくれています. 特に茶色のときは問題へのとっかかり, 具体的なコードの書き方などかなり参考になりました.

復習について

 私は各問題のコードを残してあるので, AC後の復習として, そのファイルのコメントアウトに解くために必要な思考を書いています. これの便利な点としてはVS Codeの検索マークから全ファイルの内容についてキーワード検索ができるところです. これにより「ダイクストラ法で解けそうだけど実装忘れた...」といった時にコメントアウトのワードが検索に引っかかって, すぐにファイルを持ってくることができます.

スクリーンショット 2026-03-02 174302.png

スクリーンショット 2026-03-02 174500.png

環境について

 私の競プロ環境について記しておきます.

  • PC:Windows11 ノートパソコン
  • コードエディタ:VS Code
  • ブラウザ:Google Chrome

おそらくかなり普通だと思います. 私はスニペットに力を入れていて私のcppファイルのテンプレートを以下に置いておきます. 利用はご自由にどうぞ.

cppファイルのテンプレート
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <numeric>
#include <cmath>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <functional>
#include <ranges>
#include <cctype>
#include <iomanip>
using namespace std;

#include <boost/multiprecision/cpp_int.hpp>
using namespace boost::multiprecision;

#include <atcoder/all>
using namespace atcoder;

using ll = long long;
using ull = unsigned long long;
using ld = long double;
using pll = pair<ll, ll>;
using vpll = vector<pll>;
using vvpll = vector<vpll>;
using vl = vector<ll>;
using vvl = vector<vl>;
using vb = vector<bool>;
using vvb = vector<vb>;
using vs = vector<string>;
using vc = vector<char>;
using vvc = vector<vc>;
using pq = priority_queue<ll>;
using pq_min = priority_queue<ll, vector<ll>, greater<ll>>; //小さい順
using mint = modint998244353;
using bint = cpp_int;

const ll INF = 8'000'000'000'000'000'000LL; // 8*10^18
const ll MOD = 998244353;
const ld pi = 3.141592653589793238;
const string abc = "abcdefghijklmnopqrstuvwxyz";
const string ABC = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const int dy4[4] = {-1,0,1,0};
const int dx4[4] = {0,1,0,-1};
const int dy8[8] = {-1, -1, 0, 1, 1, 1, 0, -1};
const int dx8[8] = {0, 1, 1, 1, 0, -1, -1, -1};

#define rep(i, a, n) for (ll i = a; i < (ll)(n); ++i)
#define rrep(i, a, n) for (ll i = (ll)(n) - 1; i >= a; --i)
#define all(x) (x).begin(), (x).end()
#define sz(x) (ll)(x).size()
#define Yes cout << "Yes" << endl
#define No cout << "No" << endl
#define out(x) cout << x << "\n"
#define fix cout << fixed <<  setprecision(15)

template<class T> bool chmax(T &a, const T &b) {
    if (a < b) { a = b; return true; }
    return false;
}
template<class T> bool chmin(T &a, const T &b) {
    if (a > b) { a = b; return true; }
    return false;
}

void solve() {
    // ロジックをちゃんと考える!!!
    
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    // テストケースが1つの場合
    solve();

    // テストケースが複数ある場合
    // int t;
    // cin >> t;
    // while (t--) {
    //     solve();
    // }
    return 0;
}

また, VS Code用のcpp.json(スニペットをまとめたファイル)も以下に置いておきます. これには各種ライブラリ(UFやセグ木, 強連結成分分解), 便利な関数(進数変換や任意のmodをとった累乗), DFSやBFSの雛形を含んでいます.

cpp.json
{
	"atcoder": {
		"prefix": "atcoder",
		"body": [
			"#include <iostream>",
			"#include <vector>",
			"#include <string>",
			"#include <algorithm>",
			"#include <numeric>",
			"#include <cmath>",
			"#include <map>",
			"#include <set>",
			"#include <queue>",
			"#include <stack>",
			"#include <functional>",
			"#include <ranges>",
			"#include <cctype>",
			"#include <iomanip>",
			"using namespace std;",
			"",
			"#include <boost/multiprecision/cpp_int.hpp>",
			"using namespace boost::multiprecision;",
			"",
			"#include <atcoder/all>",
			"using namespace atcoder;",
			"",
			"using ll = long long;",
			"using ull = unsigned long long;",
			"using ld = long double;",
			"using pll = pair<ll, ll>;",
			"using vpll = vector<pll>;",
			"using vvpll = vector<vpll>;",
			"using vl = vector<ll>;",
			"using vvl = vector<vl>;",
			"using vb = vector<bool>;",
			"using vvb = vector<vb>;",
			"using vs = vector<string>;",
			"using vc = vector<char>;",
			"using vvc = vector<vc>;",
			"using pq = priority_queue<ll>;",
			"using pq_min = priority_queue<ll, vector<ll>, greater<ll>>; //小さい順",
			"using mint = modint998244353;",
			"using bint = cpp_int;",
			"",
			"const ll INF = 8'000'000'000'000'000'000LL; // 8*10^18",
			"const ll MOD = 998244353;",
			"const ld pi = 3.141592653589793238;",
			"const string abc = \"abcdefghijklmnopqrstuvwxyz\";",
			"const string ABC = \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\";",
			"const int dy4[4] = {-1,0,1,0};",
			"const int dx4[4] = {0,1,0,-1};",
			"const int dy8[8] = {-1, -1, 0, 1, 1, 1, 0, -1};",
			"const int dx8[8] = {0, 1, 1, 1, 0, -1, -1, -1};",
			"",
			"#define rep(i, a, n) for (ll i = a; i < (ll)(n); ++i)",
			"#define rrep(i, a, n) for (ll i = (ll)(n) - 1; i >= a; --i)",
			"#define all(x) (x).begin(), (x).end()",
			"#define sz(x) (ll)(x).size()",
			"#define Yes cout << \"Yes\" << endl",
			"#define No cout << \"No\" << endl",
			"#define out(x) cout << x << \"\\n\"",
			"#define fix cout << fixed <<  setprecision(15)",
			"",
			"template<class T> bool chmax(T &a, const T &b) {",
			"    if (a < b) { a = b; return true; }",
			"    return false;",
			"}",
			"template<class T> bool chmin(T &a, const T &b) {",
			"    if (a > b) { a = b; return true; }",
			"    return false;",
			"}",
			"",
			"void solve() {",
			"\t// ロジックをちゃんと考える!!!",
			"    $0",
			"}",
			"",
			"int main() {",
			"    ios_base::sync_with_stdio(false);",
			"    cin.tie(nullptr);",
			"    // テストケースが1つの場合",
			"    solve();",
			"",
			"    // テストケースが複数ある場合",
			"    // int t;",
			"    // cin >> t;",
			"    // while (t--) {",
			"    //     solve();",
			"    // }",
			"    return 0;",
			"}",
		],
		"description": "Atcoderのc++テンプレート",
	},
	"outOfGrid": {
		"prefix": "outOfGridSnippet",
		"body": [
			"bool outOfGrid(ll y, ll x, ll H, ll W) {",
			"    return (y < 0 || x < 0 || y >= H || x >= W);",
			"}",
		],
		"description": "グリッドの範囲外除去",
	},
	"rle": {
		"prefix": "rleSnippet",
		"body": [
			"    vpll rle;",
			"    rle.push_back({A[0], 1});",
			"    rep(i, 1, sz(A)){",
			"        if(A[i]==rle.back().first) rle.back().second++;",
			"        else rle.push_back({A[i], 1});",
			"    }",
		],
		"description": "ランレングス圧縮",
	},
	"isPal": {
		"prefix": "isPalSnippet",
		"body": [
			"bool isPal(const string& s) {",
			"    for (ll i = 0, j = s.size() ? s.size() - 1 : 0; i < j; ++i, --j) {",
			"        if (s[i] != s[j]) return false;",
			"    }",
			"    return true;",
			"}",
		],
		"description": "回文判定",
	},
	"sumOfDigit": {
		"prefix": "sumOfDigitSnippet",
		"body": [
			"ll sumOfDigit(ll n) {",
			"    ll sum = 0;",
			"    while (n > 0) {",
			"        sum += n % 10; n /= 10;",
			"    }",
			"    return sum;",
			"}",
		],
		"description": "桁和",
	},
	"twoPointer": {
		"prefix": "twoPointerSnippet",
		"body": [
			"    ll r=0;",
			"    rep(i, 0, N){",
			"        while(r<N && /* 条件を満たす場合 */){",
			"          /* rightを進める処理 */",
			"          r++;",
			"        }",
			"        /* ansの更新など */",
			"    }",
		],
		"description": "尺取り法",
	},
	"nCrMint": {
		"prefix": "nCrMintSnippet",
		"body": [
			"mint nCr (ll n, ll r){",
			"\tmint a=1, b=1;",
			"\trrep(i, n-r+1, n+1) a*=i;",
			"\trep(i, 1, r+1) b*=i;",
			"\tmint res =  a*(b.pow((ll)(mint::mod())-2));",
			"\treturn res.val();",
			"}"
		],
		"description": "組み合わせ",
	},
	"modPow": {
		"prefix": "modPowSnippet",
		"body": [
			"ll modPow(ll a, ll b, ll m) {",
			"    ll res = 1;",
			"    a %= m;",
			"    while (b > 0) {",
			"        if (b & 1) res = res * a % m;",
			"        a = a * a % m;",
			"        b >>= 1;",
			"    }",
			"    return res;",
			"}"
		],
		"description": "累乗(繰り返し二乗法)"
	},
	"primes": {
		"prefix": "primesSnippet",
		"body": [
			"    // 1e7以下の数に対するエラトステネスの篩",
			"    vl primes; // 素数",
			"    vb deleted(10'000'000LL); //true:すでにチェック済み",
			"    rep(i, 2, 10'000'000LL+1){",
			"        if(deleted[i]) continue;",
			"        primes.push_back(i);",
			"        for(int j=i+i;j<10'000'000LL+1;j+=i) deleted[j]=true;",
			"    }",
		],
		"description": "エラトステネスの篩",
	},
	"base": {
		"prefix": "baseSnippet",
		"body": [
			"// A進法の string -> 10進法の ll",
			"ll baseToDec(const string& S, ll A) {",
			"    ll res = 0;",
			"    for (char c : S) {",
			"        ll digit;",
			"        if (c >= '0' && c <= '9') {",
			"            digit = c - '0';",
			"        } else {",
			"            digit = c - 'A' + 10; // 11進法以上 (A~Z) に対応",
			"        }",
			"        res = res * A + digit;",
			"    }",
			"    return res;",
			"}",
			"",
			"// 10進法の ll -> A進法の string",
			"string decToBase(ll N, ll A) {",
			"    if (N == 0) return \"0\";",
			"    ",
			"    string res = \"\";",
			"    while (N > 0) {",
			"        int rem = N % A;",
			"        if (rem < 10) {",
			"            res += (char)('0' + rem);",
			"        } else {",
			"            res += (char)('A' + rem - 10); // 11進法以上 (A~Z) に対応",
			"        }",
			"        N /= A;",
			"    }",
			"    // 下の桁から順番に文字列に足されているので、最後に反転させる",
			"    reverse(res.begin(), res.end());",
			"    ",
			"    return res;",
			"}"
		],
		"description": "進数変換"
	},
	"UnionFind": {
		"prefix": "UnionFindSnippet",
		"body": [
			"struct UnionFind {",
			"    std::vector<int> parent_or_size;",
			"",
			"    UnionFind(int n) : parent_or_size(n, -1) {}",
			"",
			"    int leader(int a) {",
			"        if (parent_or_size[a] < 0) {",
			"            return a;",
			"        }",
			"        return parent_or_size[a] = leader(parent_or_size[a]);",
			"    }",
			"",
			"    int merge(int a, int b) {",
			"        int x = leader(a);",
			"        int y = leader(b);",
			"        if (x == y) return x;",
			"        ",
			"        if (-parent_or_size[x] < -parent_or_size[y]) {",
			"            std::swap(x, y);",
			"        }",
			"        ",
			"        parent_or_size[x] += parent_or_size[y];",
			"        parent_or_size[y] = x;",
			"        return x;",
			"    }",
			"",
			"    bool same(int a, int b) {",
			"        return leader(a) == leader(b);",
			"    }",
			"",
			"    int size(int a) {",
			"        return -parent_or_size[leader(a)];",
			"    }",
			"",
			"    std::vector<std::vector<int>> groups() {",
			"        int n = parent_or_size.size();",
			"        std::vector<int> leader_buf(n), group_size(n);",
			"        for (int i = 0; i < n; i++) {",
			"            leader_buf[i] = leader(i);",
			"            group_size[leader_buf[i]]++;",
			"        }",
			"        ",
			"        std::vector<std::vector<int>> result(n);",
			"        for (int i = 0; i < n; i++) {",
			"            result[i].reserve(group_size[i]);",
			"        }",
			"        for (int i = 0; i < n; i++) {",
			"            result[leader_buf[i]].push_back(i);",
			"        }",
			"        ",
			"        std::vector<std::vector<int>> final_result;",
			"        for (int i = 0; i < n; i++) {",
			"            if (!result[i].empty()) {",
			"                final_result.push_back(std::move(result[i]));",
			"            }",
			"        }",
			"        return final_result;",
			"    }",
			"};"
		],
		"description": "Union-Find"
	},
	"SegTree": {
		"prefix": "SegTreeSnippet",
		"body": [
			"template <class S, S (*op)(S, S), S (*e)()>",
			"struct segtree {",
			"  public:",
			"    segtree() : segtree(0) {}",
			"    explicit segtree(int n) : segtree(std::vector<S>(n, e())) {}",
			"    explicit segtree(const std::vector<S>& v) : _n(int(v.size())) {",
			"        size = 1;",
			"        while (size < _n) size *= 2;",
			"        d = std::vector<S>(2 * size, e());",
			"        for (int i = 0; i < _n; i++) d[size + i] = v[i];",
			"        for (int i = size - 1; i >= 1; i--) update(i);",
			"    }",
			"",
			"    void set(int p, S x) {",
			"        assert(0 <= p && p < _n);",
			"        p += size;",
			"        d[p] = x;",
			"        for (int i = p >> 1; i >= 1; i >>= 1) update(i);",
			"    }",
			"",
			"    S get(int p) const {",
			"        assert(0 <= p && p < _n);",
			"        return d[p + size];",
			"    }",
			"",
			"    S prod(int l, int r) const {",
			"        assert(0 <= l && l <= r && r <= _n);",
			"        S sml = e(), smr = e();",
			"        l += size;",
			"        r += size;",
			"        while (l < r) {",
			"            if (l & 1) sml = op(sml, d[l++]);",
			"            if (r & 1) smr = op(d[--r], smr);",
			"            l >>= 1;",
			"            r >>= 1;",
			"        }",
			"        return op(sml, smr);",
			"    }",
			"",
			"    S all_prod() const { return d[1]; }",
			"",
			"    template <bool (*f)(S)> int max_right(int l) const {",
			"        return max_right(l, [](S x) { return f(x); });",
			"    }",
			"    template <class F> int max_right(int l, F f) const {",
			"        assert(0 <= l && l <= _n);",
			"        assert(f(e()));",
			"        if (l == _n) return _n;",
			"        l += size;",
			"        S sm = e();",
			"        do {",
			"            while (l % 2 == 0) l >>= 1;",
			"            if (!f(op(sm, d[l]))) {",
			"                while (l < size) {",
			"                    l = (2 * l);",
			"                    if (f(op(sm, d[l]))) {",
			"                        sm = op(sm, d[l]);",
			"                        l++;",
			"                    }",
			"                }",
			"                return l - size;",
			"            }",
			"            sm = op(sm, d[l]);",
			"            l++;",
			"        } while ((l & -l) != l);",
			"        return _n;",
			"    }",
			"",
			"    template <bool (*f)(S)> int min_left(int r) const {",
			"        return min_left(r, [](S x) { return f(x); });",
			"    }",
			"    template <class F> int min_left(int r, F f) const {",
			"        assert(0 <= r && r <= _n);",
			"        assert(f(e()));",
			"        if (r == 0) return 0;",
			"        r += size;",
			"        S sm = e();",
			"        do {",
			"            r--;",
			"            while (r > 1 && (r % 2)) r >>= 1;",
			"            if (!f(op(d[r], sm))) {",
			"                while (r < size) {",
			"                    r = (2 * r + 1);",
			"                    if (f(op(d[r], sm))) {",
			"                        sm = op(d[r], sm);",
			"                        r--;",
			"                    }",
			"                }",
			"                return r + 1 - size;",
			"            }",
			"            sm = op(d[r], sm);",
			"        } while ((r & -r) != r);",
			"        return 0;",
			"    }",
			"",
			"  private:",
			"    int _n, size;",
			"    std::vector<S> d;",
			"",
			"    void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }",
			"};"
		],
		"description": "セグ木"
	},
	"FenwickTree": {
		"prefix": "FenwickTreeSnippet",
		"body": [
			"template <class T>",
			"struct fenwick_tree {",
			"    int _n;",
			"    std::vector<T> data;",
			"",
			"    fenwick_tree(int n) : _n(n), data(n + 1, 0) {}",
			"",
			"    void add(int p, T x) {",
			"        assert(0 <= p && p < _n);",
			"        p++;",
			"        while (p <= _n) {",
			"            data[p] += x;",
			"            p += p & -p;",
			"        }",
			"    }",
			"",
			"    T sum(int r) const {",
			"        assert(0 <= r && r <= _n);",
			"        T s = 0;",
			"        while (r > 0) {",
			"            s += data[r];",
			"            r -= r & -r;",
			"        }",
			"        return s;",
			"    }",
			"",
			"    T sum(int l, int r) const {",
			"        assert(0 <= l && l <= r && r <= _n);",
			"        return sum(r) - sum(l);",
			"    }",
			"};"
		],
		"description": "フェニック木"
	},
	"Comb": {
		"prefix": "CombSnippet",
		"body": [
			"ll modPow(ll a, ll b, ll m) {",
			"    ll res = 1;",
			"    a %= m;",
			"    while (b > 0) {",
			"        if (b & 1) res = res * a % m;",
			"        a = a * a % m;",
			"        b >>= 1;",
			"    }",
			"    return res;",
			"}",
			"",
			"struct Comb {",
			"    int MAX;",
			"    ll MOD;",
			"    std::vector<ll> fact, finv;",
			"",
			"    Comb(int max_n, ll mod) : MAX(max_n), MOD(mod), fact(max_n), finv(max_n) {",
			"        fact[0] = 1;",
			"        for (int i = 1; i < MAX; i++) {",
			"            fact[i] = fact[i - 1] * i % MOD;",
			"        }",
			"",
			"        finv[MAX - 1] = modPow(fact[MAX - 1], MOD - 2, MOD);",
			"        for (int i = MAX - 2; i >= 0; i--) {",
			"            finv[i] = finv[i + 1] * (i + 1) % MOD;",
			"        }",
			"    }",
			"",
			"    ll nCr(int n, int k) {",
			"        if (n < k || n < 0 || k < 0) return 0;",
			"        return fact[n] * (finv[k] * finv[n - k] % MOD) % MOD;",
			"    }",
			"    ",
			"    ll nPr(int n, int k) {",
			"        if (n < k || n < 0 || k < 0) return 0;",
			"        return fact[n] * finv[n - k] % MOD;",
			"    }",
			"};"
		],
		"description": "組み合わせ"
	},
	"SCC": {
		"prefix": "SCCSnippet",
		"body": [
			"struct scc_graph {",
			"    int n;",
			"    std::vector<std::vector<int>> g, rg;",
			"    std::vector<int> order;",
			"    std::vector<bool> used;",
			"",
			"    scc_graph(int _n) : n(_n), g(_n), rg(_n) {}",
			"",
			"    void add_edge(int from, int to) {",
			"        g[from].push_back(to);",
			"        rg[to].push_back(from);",
			"    }",
			"",
			"    void dfs(int v) {",
			"        used[v] = true;",
			"        for (int u : g[v]) {",
			"            if (!used[u]) dfs(u);",
			"        }",
			"        order.push_back(v);",
			"    }",
			"",
			"    void rdfs(int v, std::vector<int>& comp) {",
			"        used[v] = true;",
			"        comp.push_back(v);",
			"        for (int u : rg[v]) {",
			"            if (!used[u]) rdfs(u, comp);",
			"        }",
			"    }",
			"",
			"    std::vector<std::vector<int>> scc() {",
			"        used.assign(n, false);",
			"        order.clear();",
			"        for (int i = 0; i < n; i++) {",
			"            if (!used[i]) dfs(i);",
			"        }",
			"        ",
			"        used.assign(n, false);",
			"        std::vector<std::vector<int>> res;",
			"        for (int i = n - 1; i >= 0; i--) {",
			"            int v = order[i];",
			"            if (!used[v]) {",
			"                std::vector<int> comp;",
			"                rdfs(v, comp);",
			"                res.push_back(comp);",
			"            }",
			"        }",
			"        return res;",
			"    }",
			"};"
		],
		"description": "強連結成分分解"
	},
	"Dijkstra": {
		"prefix": "DijkstraSnippet",
		"body": [
			"    vl dist(N, INF); dist[0]=0;",
			"    priority_queue<pll, vector<pll>, greater<pll>> q;",
			"    q.push({0, 0}); //{その頂点への現時点の最小コスト, 頂点番号}",
			"",
			"    while(!q.empty()){",
			"        auto [c, to] = q.top(); q.pop();",
			"        if(dist[to]!=c) continue; //確定している",
			"        for(auto [nv, nc] : G[to]){",
			"            if(dist[nv]<=c+nc) continue; //更新せず",
			"            dist[nv]=c+nc;",
			"            q.push({c+nc, nv});",
			"        }",
			"    }"
		],
		"description": "ダイクストラ法"
	},
	"BFS": {
		"prefix": "BFSSnippet",
		"body": [
			"    vl dist(N, INF); dist[0]=0;",
			"    queue<ll> q; q.push(0);",
			"",
			"    while(!q.empty()){",
			"        auto v=q.front(); q.pop();",
			"        for(auto to : G[v]){",
			"            if(dist[to]<=dist[v]+1) continue;",
			"            dist[to]=dist[v]+1;",
			"            q.push(to);",
			"        }",
			"    }"
		],
		"description": "幅優先探索"
	},
	"DFS": {
		"prefix": "DFSSnippet",
		"body": [
			"    vb seen(N);",
			"    auto dfs = [&](auto dfs, ll v) -> void {",
			"        for(auto to : G[v]) {",
			"            if(seen[to]) continue;",
			"            seen[to]=true;",
			"            dfs(dfs, to);",
			"            // seen[to]=false;",
			"        }",
			"    };"
		],
		"description": "深さ優先探索"
	}
}

これからしたいこと

 これからの目標を記しておきます.

  • 入水
  • ヒューリスティックに参加する
  • ARC--
  • Pythonの勉強

まだまだ勉強することは尽きないなとワクワクしています.

さいごに

 この記事を読んでくださった方が楽しい競プロライフを送れることを願っております.

8
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?