全体像
#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)
- e.g.
ループ系
#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;}
参考