6
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?

More than 1 year has passed since last update.

【随時更新】AtCoderで使うC++テンプレートの解説

Posted at

全体像

#include <bits/stdc++.h>
using namespace std;
using ll=long long;
using ull=unsigned long long;
#define pb push_back
#define rep(i,n) for (int i=0; i<(n); i++)
#define reps(i,n) for (int i=1; i<=(n); i++)
#define for_(i,a,b) for (int i=(a); i<(b); i++)
#define Yes(b) ((b)?"Yes":"No")
#define YES(b) ((b)?"YES":"NO")
template <typename T> inline bool chmin(T& a, const T& b) {bool compare = a > b; if (a > b) a = b; return compare;}
template <typename T> inline bool chmax(T& a, const T& b) {bool compare = a < b; if (a < b) a = b; return compare;}
template <typename T> T gcd(T a, T b) {if (b == 0)return a; else return gcd(b, a % b);}
template <typename T> inline T lcm(T a, T b) {return (a * b) / gcd(a, b);}
template <typename T> inline T ceil(T a,T b) {return (a+(b-1))/b;}
template <typename T> inline T floor(T a,T b) {return a/b;}

int main() {

}

1. using系 (エイリアス/using宣言など)

using宣言 using namespace std

c++を使った競プロでは std ライブラリは頻出。

using namespace std;

と記述しておけば、

std::vector<int> vec1; // using宣言前
vector<int> vec2;      // using宣言後

std::cout << "Hello" << std::endl; // using宣言前
cout << "Hello" << endl;           // using宣言後

と、かなり記述量を減らすことができる。

エイリアス系

競プロでは 10^18くらいの数字が出てくる。int型は 2.1*10^9 程度でオーバーフローしてしまうので、 long 型や long long 型が頻出。

using ll=long long;
using ull=unsigned long long;

と宣言しておけば、

long long N1; // 宣言前
ll N2;        // 宣言後

このようにかなり記述量を減らすことができる。

2. 定数マクロ

push_back の省略

#define pb push_back

c++頻出のvectorに要素を追加する関数であるpush_backを省略して書く。

vector<int> vec;
vec.push_back(1); // マクロ定義前
vec.pb(1);        // マクロを使うと短く書ける!

1. 関数マクロ

  • #define マクロ名(マクロ引数) 置換テキスト で定義
  • 置換テキストの変数は必ず () で囲む
    • e.g. x ではなく (x)

ループ系

#define rep(i,n) for (int i=0; i<(n); i++)
#define reps(i,n) for (int i=1; i<=(n); i++)
#define for_(i,a,b) for (int i=(a); i<(b); i++)

repは repeat(繰り返し)の意味。
頻出の for (int i=0; i<N; i++) に加え、競プロでよく使う for (int i=1; i<=N; i++)repsとして定義。

for (int i=1; i<=N; i++) cin >> A[i]; // 宣言前
reps(i,N) cin >> A[i]; // 宣言後

リバースしたループなどもマクロに組み込んでいる人をよく見るが、それほど頻出でないため通常通りforループで記述したほうが良いと思った。
今後変わるかも。

Yes/No系

競プロでは結果をYes/NoやYES/NOで出力する問題が多い。

#define Yes(b) ((b)?"Yes":"No")
#define YES(b) ((b)?"YES":"NO")

としておけば、

// before
if (result) cout << "Yes" << endl;
else cout << "No" << endl;

// after
cout << Yes(result) << endl;

かなり簡単に記述することができる。

3. インライン関数

chmin / chmax

template <typename T> inline bool chmin(T& a, const T& b) {bool c=a>b; if(a>b) a=b; return c;}
template <typename T> inline bool chmax(T& a, const T& b) {bool c=a<b; if(a<b) a=b; return c;}

頻出の「最大値/最小値をdpなどで求める問題」によく使う。

if (a<b) {
    a = b;
    // ...
}

if (chmin(a,b)) {
    // ...
}

gcd / lcm

最大公約数/最小公倍数を求める。

template <typename T> inline T gcd(T a,T b) {return (b==0)?a:gcd(b,a%b);}
template <typename T> inline T lcm(T a, T b) {return (a*b)/gcd(a,b);}

ceil / floor

床関数、天井関数とか言われる。
切り捨てや切り上げの処理を伴う割り算を計算する。

template <typename T> inline T ceil(T a,T b) {return (a+(b-1))/b;}
template <typename T> inline T floor(T a,T b) {return a/b;}

参考

6
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
6
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?