13
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

はじめに

競プロで使える実践的なC++テンプレートを網羅的に解説する。

「このテンプレにしてからAC率上がった」って人、意外と多いんじゃない?

基本設定

#include <bits/stdc++.h>
using namespace std;

// 高速化
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    // ...
}

型定義

using ll = long long;
using ull = unsigned long long;
using ld = long double;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
using vi = vector<int>;
using vll = vector<ll>;
using vvi = vector<vi>;
using vvll = vector<vll>;
using vpii = vector<pii>;
using vpll = vector<pll>;

定数

const int INF = 1e9;
const ll LINF = 1e18;
const int MOD = 1e9 + 7;
const int MOD2 = 998244353;
const ld PI = acos(-1);
const ld EPS = 1e-9;

// 4方向・8方向
const int dx[] = {0, 1, 0, -1, 1, 1, -1, -1};
const int dy[] = {1, 0, -1, 0, 1, -1, 1, -1};

マクロ

#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define rep1(i, n) for (int i = 1; i <= (int)(n); i++)
#define rrep(i, n) for (int i = (int)(n) - 1; i >= 0; i--)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define sz(x) (int)(x).size()
#define pb push_back
#define eb emplace_back
#define fi first
#define se second
#define mp make_pair
#define mt make_tuple

便利関数

// 最小・最大更新
template<class T> bool chmin(T& a, const T& b) { 
    return b < a ? a = b, true : false; 
}
template<class T> bool chmax(T& a, const T& b) { 
    return a < b ? a = b, true : false; 
}

// 出力
template<class T> void print(const T& x) { cout << x << '\n'; }
template<class T> void print(const vector<T>& v) { 
    for (int i = 0; i < sz(v); i++) 
        cout << v[i] << " \n"[i == sz(v) - 1]; 
}

// Yes/No出力
void YN(bool b) { cout << (b ? "Yes" : "No") << '\n'; }

数学関数

ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
ll lcm(ll a, ll b) { return a / gcd(a, b) * b; }

// 繰り返し二乗法
ll mod_pow(ll x, ll n, ll mod = MOD) {
    ll res = 1;
    x %= mod;
    while (n > 0) {
        if (n & 1) res = res * x % mod;
        x = x * x % mod;
        n >>= 1;
    }
    return res;
}

// モジュラ逆元
ll mod_inv(ll a, ll mod = MOD) {
    return mod_pow(a, mod - 2, mod);
}

階乗と組み合わせ

vector<ll> fact, fact_inv;

void init_factorial(int n, ll mod = MOD) {
    fact.resize(n + 1);
    fact_inv.resize(n + 1);
    fact[0] = 1;
    rep(i, n) fact[i + 1] = fact[i] * (i + 1) % mod;
    fact_inv[n] = mod_inv(fact[n], mod);
    rrep(i, n) fact_inv[i] = fact_inv[i + 1] * (i + 1) % mod;
}

ll nCr(int n, int r, ll mod = MOD) {
    if (r < 0 || n < r) return 0;
    return fact[n] * fact_inv[r] % mod * fact_inv[n - r] % mod;
}

ll nPr(int n, int r, ll mod = MOD) {
    if (r < 0 || n < r) return 0;
    return fact[n] * fact_inv[n - r] % mod;
}

Union-Find

class UnionFind {
public:
    vector<int> par, rank_, siz;
    
    UnionFind(int n) : par(n), rank_(n, 0), siz(n, 1) {
        iota(all(par), 0);
    }
    
    int find(int x) {
        if (par[x] == x) return x;
        return par[x] = find(par[x]);  // 経路圧縮
    }
    
    void unite(int x, int y) {
        x = find(x); y = find(y);
        if (x == y) return;
        if (rank_[x] < rank_[y]) swap(x, y);
        par[y] = x;
        siz[x] += siz[y];
        if (rank_[x] == rank_[y]) rank_[x]++;
    }
    
    bool same(int x, int y) { return find(x) == find(y); }
    int size(int x) { return siz[find(x)]; }
};

セグメント木

template<typename T>
class SegmentTree {
    int n;
    vector<T> tree;
    T identity;
    function<T(T, T)> op;
    
public:
    SegmentTree(int size, T id, function<T(T, T)> operation)
        : identity(id), op(operation) {
        n = 1;
        while (n < size) n *= 2;
        tree.assign(2 * n, identity);
    }
    
    void update(int i, T x) {
        i += n;
        tree[i] = x;
        while (i > 1) {
            i /= 2;
            tree[i] = op(tree[2 * i], tree[2 * i + 1]);
        }
    }
    
    T query(int l, int r) {  // [l, r)
        T res_l = identity, res_r = identity;
        l += n; r += n;
        while (l < r) {
            if (l & 1) res_l = op(res_l, tree[l++]);
            if (r & 1) res_r = op(tree[--r], res_r);
            l /= 2; r /= 2;
        }
        return op(res_l, res_r);
    }
};

// 使用例
SegmentTree<ll> seg(n, 0, [](ll a, ll b) { return a + b; });  // 区間和
SegmentTree<ll> seg(n, LINF, [](ll a, ll b) { return min(a, b); });  // 区間最小

グラフ

using Graph = vector<vector<int>>;
using WGraph = vector<vector<pair<int, ll>>>;  // 重み付き

// BFS
vi bfs(const Graph& g, int s) {
    vi dist(sz(g), -1);
    queue<int> q;
    dist[s] = 0;
    q.push(s);
    while (!q.empty()) {
        int v = q.front(); q.pop();
        for (int u : g[v]) {
            if (dist[u] < 0) {
                dist[u] = dist[v] + 1;
                q.push(u);
            }
        }
    }
    return dist;
}

// ダイクストラ
vll dijkstra(const WGraph& g, int s) {
    vll dist(sz(g), LINF);
    priority_queue<pll, vpll, greater<pll>> pq;
    dist[s] = 0;
    pq.emplace(0, s);
    while (!pq.empty()) {
        auto [d, v] = pq.top(); pq.pop();
        if (d > dist[v]) continue;
        for (auto [u, w] : g[v]) {
            if (chmin(dist[u], dist[v] + w)) {
                pq.emplace(dist[u], u);
            }
        }
    }
    return dist;
}

実行結果

=== 型定義 ===
ll max: 1000000000000000000
pair: (1, 2)
vector: 1 2 3

=== マクロ ===
Original: 5 2 8 1 9
Sorted: 1 2 5 8 9
Reverse sorted: 9 8 5 2 1

=== chmin/chmax ===
x = 10
chmin(x, 5): x = 5
chmax(x, 15): x = 15

=== 数学関数 ===
gcd(24, 36) = 12
lcm(4, 6) = 12
2^10 mod 1e9+7 = 1024
10C3 = 120

=== Union-Find ===
same(0, 3): Yes
same(0, 4): No
size(0): 4

=== セグメント木 ===
sum[0, 5) = 15
sum[1, 4) = 9
After update(2, 10): sum[0, 5) = 22

=== BFS ===
Distance from 0: 0 1 2 3 4

=== ダイクストラ ===
Distance from 0: 0 1 3 4

完全テンプレート

#include <bits/stdc++.h>
using namespace std;

using ll = long long;
using pii = pair<int, int>;
using vi = vector<int>;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define all(x) (x).begin(), (x).end()
template<class T> bool chmin(T& a, const T& b) { return b < a ? a = b, true : false; }
template<class T> bool chmax(T& a, const T& b) { return a < b ? a = b, true : false; }

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    // ここに解答を書く
    
    return 0;
}

まとめ

このテンプレートで多くの競プロ問題に対応できます。必要に応じてカスタマイズしてください!

13
0
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
13
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?