きっとブログ
703 words
4 minutes
AtCoder用の自作ライブラリ【C++】

はじめに#

最近AtCoderを始めたのですが、自作ライブラリがあった方が何かと便利なので作ってみました。
完全版ではなく、これからもアップデートしていく予定です。

自作ライブラリ#

// mylibrary
struct Init {
    Init() {
        ios::sync_with_stdio(0);
        cin.tie(0);
        cout << setprecision(13);
    }
} init;

using ll = long long;
using ull = unsigned long long;
using pii = pair<int, int>;
using pll = pair<ll, ll>;

#define rep(i, x, limit) for (int i = (int)x; i < (int)limit; i++)
#define REP(i, x, limit) for (int i = (int)x; i <= (int)limit; i++)
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define el '\n'
#define spa " "
#define Yes cout << "Yes" << el
#define No cout << "No" << el
#define YES cout << "YES" << el
#define NO cout << "NO" << el
#define eps (1e-10)
#define Equals(a, b) (fabs((a) - (b)) < eps)

const double pi = 3.141592653589793238;
const int inf = 1073741823;
const ll infl = 1LL << 60;
const string ABC = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const string abc = "abcdefghijklmnopqrstuvwxyz";

// 配列の要素を空白区切りで出力 第二引数をtrueにすると改行区切り
template <class T>
inline void print_vec(const vector<T>& v, bool split_line = false) {
    if (v.empty()) {
        cout << "This vector is empty." << el;
        return;
    }
    for (int i = 0; i < v.size(); i++) {
        if (v[i] == inf || v[i] == infl)
            cout << 'x' << " \n"[split_line || i + 1 == (int)v.size()];
        else
            cout << v[i] << " \n"[split_line || i + 1 == (int)v.size()];
    }
}

// 2次元配列の表示
void print_vec2(const vector<vector<int>> v) {
    for (int i = 0; i < v.size(); i++) {
        for (int j = 0; j < v[i].size(); j++) {
            cout << v[i][j] << spa;
        }
        cout << el;
    }
}

// 2次元配列のソート(引数で要素を指定): 昇順バージョン
void sort_vec2(vector<vector<int>>& v, int key) {
    sort(all(v), [key](const vector<int>& alpha, const vector<int>& beta) {
        return alpha[key] < beta[key];
    });
}

// 2次元配列のソート(引数で要素を指定): 降順バージョン
void rsort_vec2(vector<vector<int>>& v, int key) {
    sort(rall(v), [key](const vector<int>& alpha, const vector<int>& beta) {
        return alpha[key] < beta[key];
    });
}

// 2つの引数のうち大きいほうを代入
template <class T>
inline bool chmax(T& a, T b) {
    return a < b ? a = b, true : false;
}

// 2つの引数のうち小さいほうを代入
template <class T>
inline bool chmin(T& a, T b) {
    return a > b ? a = b, true : false;
}

// 素数判定
bool is_prime(long long N) {
    if (N == 1) return false;
    for (long long i = 2; i * i <= N; ++i) {
        if (N % i == 0) return false;
    }
    return true;
}

// 素因数分解
template <typename T>
map<T, T> prime_factor(T n) {
    map<T, T> ret;
    for (T i = 2; i * i <= n; i++) {
        T tmp = 0;
        while (n % i == 0) {
            tmp++;
            n /= i;
        }
        ret[i] = tmp;
    }
    if (n != 1) ret[n] = 1;
    return ret;
}

// 約数の個数
template <typename T>
T divisor_num(T N) {
    map<T, T> pf = prime_factor(N);
    T ret = 1;
    for (auto p : pf) {
        ret *= (p.second + 1);
    }
    return ret;
}

// 約数を列挙
vector<long long> divisor(long long n) {
    vector<long long> ret;
    for (long long i = 1; i * i <= n; i++) {
        if (n % i == 0) {
            ret.emplace_back(i);
            if (i * i != n) ret.emplace_back(n / i);
        }
    }
    sort(ret.begin(), ret.end());  // 昇順に並べる
    return ret;
}