マクロとかテンプレートとか

以前に使っていたテンプレートとかマクロとか。
最近は誰にでも読めるコードを書くことをこころがけているので全然使っていないけど。
どうしようもなく間違っているコードが撃墜すらしてもらえないのは少し悲しいし(コードが汚いと言われている様に感じてしまう)、コンテストの戦略上でも問題がある(どうせ落ちるなら早く落としてもらいたい)。
マクロを使わなくなった別の理由として、IDEの補完機能を使ってマクロを使うのに近いことが実現できるというのもある。
gcc, g++が前提。

  • for文関連
    • 基本はFORとREP。
    • 1-indexedで考えるときのためにREPONEも定義。
    • 一々ループ変数名考えるのも面倒くさいときのためLOOP。
      • 出力に"Test Case #1"とか出力しないといけない問題があるので主にそれ用。
#define FOR(i,k,n) for((i)=(k);(i)<(n);(i)++)
#define REP(i,n) FOR(i,0,n)
#define REPONE(i,n) for((i)=1;(i)<=(n);(i)++)
#define LOOP(n) for(int loopCount=1; loopCount<=(n); loopCount++)
  • イテレータ関係
    • イテレータ回すループ文を書くのは面倒なのでEACHは結構重宝していた。
    • STLを使っているとxs.begin(), xs.end()と書く機会も多いのでALLも結構便利。
#define ITER(cs) __typeof(cs.begin())
#define EACH(cs,it) for(ITER(cs) it = cs.begin(); it != cs.end(); it++)
#define ALL(xs) xs.begin(), xs.end()
  • STLの関数
    • EXISTは線形探索しかできないので使う機会は少なかった。
    • SUMはそれなりに使う機会も多かったけど、普通にaccumulate(ALL(xs))と書くのと労力に差が無い気がする。
    • size()の返り値の型がintではないのでSZを使う機会は多かった。
#define EXIST(cs,v) (find(ALL(cs),(v))!=cs.end())
#define SUM(cs) (accumulate(ALL(cs),0))
#define SZ(cs) ((int)cs.size())
  • 長い名前の省略
    • エディタの補完機能使えばいい気もするけど。
typedef long long ll;
#define PB push_back
#define MP make_pair
#define fs first
#define sc second
  • 入力データの読み込み
    • cinが遅いのはご承知の通り。scanfでも遅いとかいうときのために書いた。
    • これを使わないとダメだった、という問題は1~2問位しかなかった気もする。
    • 上は整数を読み取る関数。Cで使うときは、boolをintに置換するとか、'-'を読み込んだらreturn -readint();するとかで対応。
    • 下は非負整数版。
inline int readint(){
    int ret = 0, x;
    bool plus = true;
    while(x=getchar(), !('0'<=x&&x<='9' || x=='-'));
    if(x=='-') plus = false;
    else ret = (x&15);
    while(x=getchar(), '0'<=x&&x<='9') ret = (ret<<3) + (ret<<1) + (x&15);
    return plus?ret:-ret;
}

inline int readint(){
    int ret = 0, x;
    while(x=getchar(), !('0'<=x&&x<='9'));
    ret = (x&15);
    while(x=getchar(), '0'<=x&&x<='9') ret = (ret<<3) + (ret<<1) + (x&15);
    return ret;
}