執筆者: 終に鮭
最終更新: 2021/03/17
共通編の続きです。 WSLを導入したWindows10、またはMac OSやLinuxなどのUNIX系OSを前提にしています。 Ubuntuなどの仮想マシンが使えるならばこの限りではありません。
C言語は説明するまでもないかと思うのでC++だけ。
C++は実行速度が速く、開発でも比較的よく使われる言語です。 イテレータや参照[1]によりポインタの操作がユーザーから秘匿されたり、クラスやテンプレートなどオブジェクト指向のパラダイムが持ち込まれたりして、C言語と比べて書きやすくなっています。 C言語との互換性が非常に高く、ポインタを直接操作することもでき、低級言語として扱うこともできます。
[1] int&型などのことです。関数にint*型で渡して関数内部で間接参照する、などとしなくても良くなっています。
2021年現在の競技プログラミング界隈では、事実上C++が標準語のようになっています。 AtCoderでは多くの言語を使うことができますが、他のコンテストサイトではあまり言語が多くなかったりします。 その中でもC++とJavaは標準的で、C++のほうが速いからか情報も多いです。 [独自研究?] そのため、競技プログラミングをするならC++は初心者におすすめの言語といえます。
C言語の環境構築もほぼ同じなので一緒に解説しますが、おまけ程度にしておきます。私は初心者がC言語を使うことはおすすめしません。 これはC言語しか習っていないうちの学生にも当てはまることなので、ぜひC++を使ってください。 一部の文法はC言語と似てるけど、便利機能モリモリで書きやすくて良いですよ。 はっきり言って、公式ガイドで環境構築できないくらいのスキルしか無いのであればC++に移行すべきだと思っています。
C++のコンパイラには主に以下の3つがあります。
GNU Compiler Collectionの一部、GNU C++ Compiler。そのコマンド名g++
からそのままg++と通称されます。
大抵のLinux OSは多くのGNUソフトウェアを標準インストールしており(GNU/Linuxの思想)、 GCC(ただしここではGNU C Compilerのこと)もそのうちに含まれています。
多くのLinuxユーザーはGNU C Compilerに馴染みがあるはずであり、GNU C++ Compilerはそれとほとんど同じオプションを利用することができます。
競プロer的に嬉しいのが、libstdc++のすべてのヘッダを読み込むbits/stdc++.h
ヘッダがあることです。 関数ごとにいちいちincludeディレクティブを書かなくていいことは記述速度最優先の競プロではプラスに働きます。 ただし実務で使うとブチ切れられることがあるらしいので気をつけてください。
多くの競プロerがGCCを使っており、なんやかんや一番おすすめです。
LLVMコンパイラ基盤の一部で、C、C++、Objective-C、Objective-C++の4言語のコンパイラ群です。
Macでは標準がClangらしいですね。他のことは何も知りません。
自分のPCにすでにClangが入っているか、GNUが嫌いでなければ特に使う理由はないと思います。
Microsoftが開発しているC++コンパイラですが、簡単に探した限りネイティブLinuxで使えるという情報は一切見つかりませんでした。当然ながらAtCoderでも対応はなし。
Intel C++ CompilerやAMD Optimizing C++ Compiler、NVIDIA HPC SDK Compilersなどのプロセッサに最適化されたコンパイラ。当然競プロで使われることはまずない。
WSL Ubuntu 20.04では必要ありません。gccもg++もGCC 9が標準搭載。やったぜ。
今後AtCoderで言語アップデートが入ってGCC 10になったときのためにインストール手順を書いておきます。
完璧にAtCoderと同じ環境にしたい場合はBoostが必要になりますが、私は使っていないのでここでは紹介しません。
忙しい人向け
sudo apt install g++-9
複数バージョンの管理もしたい人向け
# パッケージのインストール
sudo apt install g++-9
# ここから蛇足
# シンボリックリンクの書き換え
# 今回はalternativesというバージョン切り替えツールを利用する
# g++が設定済みでないことをチェック
update-alternatives --config g++
# update-alternatives: error: no alternatives for g++
# とか出ればOK
# そうでないものが出たらそのままEnterを押す
# g++にalternativesの設定を追加
# これをすると/usr/bin/g++ -> /etc/alternatives/g++ -> /usr/bin/g++-9のようなシンボリックリンクが張られる
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-9 5
g++ --version
# g++10をインストール
sudo apt install g++-10
# 優先度10なので、こちらのほうが優先度が高くなる
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-10 10
g++ --version
# マニュアルモードでバージョンを戻しておく
sudo update-alternatives --config g++
alternativesの部分はg++
を全部gcc
に書き換えればいいだけなので省略します。
sudo apt install gcc-9
AtCoderのコンテストのルールのページを見ればコマンドが書いてあります。
https://atcoder.jp/contests/abc194/rules より引用。
g++ -std=gnu++17 -Wall -Wextra -O2 -DONLINE_JUDGE -I/opt/boost/gcc/include -L/opt/boost/gcc/lib -I/opt/ac-library -o ./a.out ./Main.cpp
#include<>
の検索対象に含めます#include<>
の検索対象に含めます./a.out
にします-DHOGE=FUGA
は入力ファイルの先頭に#define HOGE FUGA
とするのと同じ効果を持ちます。 FUGA
が省略され-DHOGE
と書かれた場合、#define HOGE "1"
とするのと同じ効果を持ちます。 Includeガードでよくやるやつですね。
AtCoder Libraryは AtCoderのジャッジで利用することができるオープンソースなC++ライブラリです (つまりC言語は対象外、移植は様々な言語にあります。 C言語版はここ。 アクティブなプロジェクトで、C++ STLのデータ構造(set
やmap
等)も移植対象とするようなので、 C言語使いの皆さん、是非プルリク出してあげてください)。 一般的な開発にはあまり使われない、しかし競技プログラミングでは重宝されるような機能が多数備わっています。
具体的には
などが含まれます(その他にも多数あります)。
ここのGitHubリポジトリからダウンロードしてきます。 zipファイルをダウンロードして解凍してもよいのですが、 WSL Ubuntuにはunzip
はデフォルトで入っていないようなのでgit clone
でダウンロードすることにします。なぜgitはデフォルトで入ってるんだろう。使うからええんやけどさ
# /opt下にダウンロード
cd /opt
sudo git clone https://github.com/atcoder/ac-library.git
# インクルードできるかチェック
g++ -I/opt/ac-library ./acl_include.cpp
acl_include.cpp
の中身
#include <atcoder/all>
int main() {
return 0;
}
以上。
毎回-I
オプションを付けるのが面倒な方は、環境変数CPLUS_INCLUDE_PATH
にパスを付け足せばよいです。
.bash_profile
export CPLUS_INCLUDE_PATH="$CPLUS_INCLUDE_PATH:/opt/ac-library"
# .bash_profileを書くと.bashrcが読まれなくなるので、こっちから読み込むように指示
source ~/.bashrc
適用できたか確認
source ~/.bash_profile
g++ acl_include.cpp
-I
オプションを付けるのが面倒な方は~、なんて言いましたが、どちらにせよ-std=gnu++17
などのオプションはつけるべきです。 しかし面倒くさい。そのためのエイリアス。.bash_aliases
にでも次のように付け足しましょう
alias g++-ac='g++ -std=gnu++17 -Wall -Wextra -O2'
とりあえずこれだけあれば十分かなと思いますが、好みに応じて増やしたり減らしたりしてください。
atcoder-cliのテンプレートに設定しておくとよいです。 私はこれで十分だと思っていますが、extgcdやdijkstraなど、ライブラリを付けたい方は付けてください。
#include <bits/stdc++.h>
#include <atcoder/all>
using namespace std;
// using namespace atcoder;
using ll = long long;
const ll MOD = 1000000007LL;
// const ll MOD = 998244353LL;
const vector<pair<int, int>> dpos4 = {{-1, 0}, {0, -1}, {0, 1}, {1, 0}};
// const vector<pair<int, int>> dpos8 = {{-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, {0, 1}, {1, -1}, {1, 0}, {1, 1}};
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
return 0;
}
bits/stdc++.h
を使うとコンパイル速度はかなり落ちます。 何度もテストする場合、それぞれの機能ごとに逐一includeしたほうが良いかもしれません。 少なくとも、手元環境で使う場合はプリコンパイルしておきましょう。
# sudoをエイリアスで書き換えるというヤバいことをするので新しいシェルに入る
bash
# エイリアスの末尾がホワイトスペースのとき、次のトークンがエイリアスかチェックするらしい
# g++-acエイリアスを使わない場合はこれをする必要はない
# CPLUS_INCLUDE_PATHを設定済みの場合-Eオプション(環境変数を引き継ぐ)は必須
# 参考:https://qiita.com/homines22/items/ba1a6d03df85e65fc85a
alias sudo='sudo -E '
# 本体部分
for header in `find /usr -type f -name 'stdc++.h'`; do
sudo g++-ac $header
done
# 立ち上げたシェルから抜ける
exit
# PCHが生成されたことを確認
find /usr -type f -name 'stdc++.h.gch'
次回はPythonです。こちらで検証に成功すればnumbaの導入までやりたいですね。
この人が書いた記事