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

# 全体像
```c++
#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` ライブラリは頻出。
```c++
using namespace std;
```
と記述しておけば、
```c++
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` 型が頻出。
```c++
using ll=long long;
using ull=unsigned long long;
```
と宣言しておけば、
```c++
long long N1; // 宣言前
ll N2;        // 宣言後
```
このようにかなり記述量を減らすことができる。




# 2. 定数マクロ

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

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

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

## ループ系

```c++
#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`として定義。
```c++
for (int i=1; i<=N; i++) cin >> A[i]; // 宣言前
reps(i,N) cin >> A[i]; // 宣言後
```
リバースしたループなどもマクロに組み込んでいる人をよく見るが、それほど頻出でないため通常通りforループで記述したほうが良いと思った。
今後変わるかも。


## Yes/No系
競プロでは結果をYes/NoやYES/NOで出力する問題が多い。
```c++
#define Yes(b) ((b)?"Yes":"No")
#define YES(b) ((b)?"YES":"NO")
```
としておけば、
```c++
// before
if (result) cout << "Yes" << endl;
else cout << "No" << endl;

// after
cout << Yes(result) << endl;
```
かなり簡単に記述することができる。


# 3. インライン関数

## `chmin` / `chmax`
```c++
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などで求める問題」によく使う。
```c++
if (a<b) {
    a = b;
    // ...
}

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

## `gcd` / `lcm`
最大公約数/最小公倍数を求める。
```c++
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`
床関数、天井関数とか言われる。
切り捨てや切り上げの処理を伴う割り算を計算する。
```c++
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;}
```






# 参考
https://qiita.com/luftfararen/items/8f9fb52d43f0c76ca932

https://qiita.com/eierapfel/items/3581ab2d3c63956a1791