Problem:
Problem J: 問題文担当者は働かない！
N
個の点からなる有向グラフがある。このグラフに閉路はない。それぞれの点には、いくつかの石が置かれている。このグラフを使って、２人のプレイヤーがゲームをする。おのおのの手番は、交互に訪れる。各プレイヤーは、自分の手番において、頂点
v
を選び、そこに置かれた石を１つ以上取り除く。その後、
v
から
w
に辺が張られているすべての頂点
w
について、
w
に置かれている石の個数を自由に変化させることができる（いくつ増やしても、いくつ減らしても、変化させなくてもよい）。これを繰り返して、最初に取る石がなくなった方の負けである。両者が最善をつくしたとき、先手と後手、どちらが勝つか。もしくは、いつまでもゲームが終わらないか。
「……いや、無理でしょう、これ」
「何が？」
「何がじゃなくて！　これにどうやって自然な問題設定をつけろって言うんですか」
「ははは。それを考えるのが君の仕事じゃないか。文章担当だろう？」
「丸投げにもほどがありますよ……。まずゲームのルールが不自然すぎるでしょう」
「そうかなぁ？　僕はよくある石取りゲームだと思うけどね」
「プレイヤーの意思で石を無尽蔵に増やせる石取りゲームがよくあってたまりますか！」
「お。君、今うまいこと言ったね」
「ええ、意思で石を……ってどうでもいいわ！　そっちも少しは考えてくださいよ」
「そうだねぇ。縊死した医師の遺志を継ぐ遺子の意思で石を取る、なんてどうだい？」
「考えるのはそこじゃねぇよ！　石取りゲームの話だよ！」
「違うのかい？　でも『取り』は鳥くらいしか同音異義語がなくて難しいんだよね」
「いったん言葉遊びから離れろや！　自然な問題設定を考えてくれって言ってるんですよ！」
「だからそれは君の仕事だろうに。僕はただの仲介役。原案担当と文章担当の間をとりもつだけさ」
「くそ……。原案担当め、どうしてこんな厄介な問題を……」
「原案担当者から君へのメッセージ。『フヒヒｗ　存分に苦しめ文章担当ｗｗ』だそうだよ」
「畜生あの野郎！　いつか一発殴る！」
「まあ、僕の『石が増える石取りゲームなんて実に設定がつけにくいと思わないかい？』ってアドバ
イスのおかげもあるだろうけどね」
「畜生お前もか！　いつかと言わず今殴る！」
「はっはっは。君が締め切りまでに文章担当としての役割を果たせないようなら、僕が勝手に問題文
を書いちゃうよ？」
「殴……って、え？　お前が書いてくれんの？」
「タイトルは『問題文担当者は働かない！』。本文には、僕たちのこの会話をそのまま掲載」
「頼むからやめて！　そんなふざけた問題が自分名義で世に出たら、これから皆になんて言われる
か！」
「はっはっは。締め切りも守れないような奴は、社会的に抹殺されて当然だよね」
「畜生！　こうなったら、意地でも自然な問題設定を思いついてやらあああああ！」
（※　結局そのまま掲載されました）
Input
N M
v
1
v
2
.
.
.
v
N
a
1
b
1
a
2
b
2
.
.
.
a
M
b
M
入力の１行目には、整数
N
（2 ≤
N
≤ 1,000）と整数
M
（1 ≤
M
≤ 10,000）が、空白区切りで書かれている。これは、有向グラフがN 個の点と
M
本の辺からなることをあらわす。頂点には、1 番から
N
番までの番号がふられている。
続く
N
行には、整数
v
i
（1 ≤
v
i
≤ 10,000）が書かれている。１＋ i 行目に書かれた整数
v
i
は、i 番の点に最初はvi 個の石が置かれていることをあらわす。
続く
M
行には、整数
a
i
（1 ≤
a
i
≤
N
）と整数
b
i
（1 ≤
b
i
≤
N
）が、空白区切りで書かれている。１＋
N
＋ i 行目に書かれた整数
a
i
と
b
i
は、
a
i
番の点から
b
i
番の点へ張られている辺が存在することをあらわす。ある点から自分自身へと張られる辺は存在せず、ある点A からある点B へ張られる辺は高々１本である。
与えられた有向グラフには閉路がないと仮定してよい。
Output
両プレイヤーが自身の勝利を目指して最善をつくしたとき、先手が勝つならば1 を、後手が勝つなら
ば2 を、いつまでもゲームが終わらないならば0 を出力せよ。
Sample Input 1
6 5
7
14
5
11
2
5
1 2
2 3
3 4
4 5
5 6
Sample Output 1
2
Sample Input 2
5 7
295
127
350
982
426
1 5
3 5
4 2
3 1
3 4
5 4
3 2
Sample Output 2
1
Sample Input 3
8 7
6
1
7
2
5
2
6
3
1 3
6 3
7 4
4 2
1 6
5 4
7 5
Sample Output 3
2

Submitted solutions:

code_snippet: #define _USE_MATH_DEFINES
#include <algorithm>
#include <cstdio>
#include <functional>
#include <iostream>
#include <cfloat>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <time.h>
#include <vector>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> i_i;
typedef pair<ll, int> ll_i;
typedef pair<double, int> d_i;
typedef pair<ll, ll> ll_ll;
typedef pair<double, double> d_d;
struct edge { int u, v; ll w; };

ll MOD = 1000000007;
ll _MOD = 1000000009;
double EPS = 1e-10;

int main() {
	int N, M; cin >> N >> M;
	vector<int> a(N);
	for (int u = 0; u < N; u++)
		cin >> a[u];
	vector<int> d(N);
	vector<vector<int> > G(N);
	while (M--) {
		int u, v; cin >> u >> v;
		u--; v--;
		d[u]++;
		G[v].push_back(u);
	}
	vector<vector<bool> > b(N, vector<bool>(1<<16));
	for (int u = 0; u < N; u++)
		b[u][0] = true;
	queue<int> q;
	for (int u = 0; u < N; u++)
		if (!d[u])
			q.push(u);
	int X = 0;
	while (!q.empty()) {
		int u = q.front(); q.pop();
		int x;
		for (x = 0; b[u][x]; x++);
		if (a[u] % 2) X ^= x;
		for (int v: G[u]) {
			vector<bool> _b = b[v];
			for (int y = 0; y < 1<<16; y++)
				if (b[v][y])
					_b[y ^ x] = true;
			b[v] = _b;
			d[v]--;
			if (!d[v]) q.push(v);
		}
	}
	cout << (X ? 1 : 2) << endl;
}
accuracy: 0.45
time_ms: 110
memory_kb: 7544
final_rank: 4

code_snippet: #define _USE_MATH_DEFINES
#include <algorithm>
#include <cstdio>
#include <functional>
#include <iostream>
#include <cfloat>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <time.h>
#include <vector>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> i_i;
typedef pair<ll, int> ll_i;
typedef pair<double, int> d_i;
typedef pair<ll, ll> ll_ll;
typedef pair<double, double> d_d;
struct edge { int u, v; ll w; };

ll MOD = 1000000007;
ll _MOD = 1000000009;
double EPS = 1e-10;

int main() {
	int N, M; cin >> N >> M;
	vector<int> a(N);
	for (int u = 0; u < N; u++)
		cin >> a[u];
	vector<int> d(N);
	vector<vector<int> > G(N);
	while (M--) {
		int u, v; cin >> u >> v;
		u--; v--;
		d[u]++;
		G[v].push_back(u);
	}
	vector<vector<bool> > b(N, vector<bool>(1<<15));
	for (int u = 0; u < N; u++)
		b[u][0] = true;
	queue<int> q;
	for (int u = 0; u < N; u++)
		if (!d[u])
			q.push(u);
	int X = 0;
	while (!q.empty()) {
		int u = q.front(); q.pop();
		int x;
		for (x = 0; b[u][x]; x++);
		if (a[u] % 2) X ^= x;
		for (int v: G[u]) {
			vector<bool> _b = b[v];
			for (int y = 0; y < 1<<15; y++)
				if (b[v][y])
					_b[y ^ x] = true;
			b[v] = _b;
			d[v]--;
			if (!d[v]) q.push(v);
		}
	}
	cout << (X ? 1 : 2) << endl;
}
accuracy: 0.45
time_ms: 50
memory_kb: 5180
final_rank: 3

code_snippet: #define _USE_MATH_DEFINES
#include <algorithm>
#include <cstdio>
#include <functional>
#include <iostream>
#include <cfloat>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <time.h>
#include <vector>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> i_i;
typedef pair<ll, int> ll_i;
typedef pair<double, int> d_i;
typedef pair<ll, ll> ll_ll;
typedef pair<double, double> d_d;
struct edge { int u, v; ll w; };

ll MOD = 1000000007;
ll _MOD = 1000000009;
double EPS = 1e-10;

int main() {
	int N, M; cin >> N >> M;
	vector<int> a(N);
	for (int u = 0; u < N; u++)
		cin >> a[u];
	vector<int> d(N);
	vector<vector<int> > G(N);
	while (M--) {
		int u, v; cin >> u >> v;
		u--; v--;
		d[u]++;
		G[v].push_back(u);
	}
	vector<vector<bool> > b(N, vector<bool>(1<<14));
	for (int u = 0; u < N; u++)
		b[u][0] = true;
	queue<int> q;
	for (int u = 0; u < N; u++)
		if (!d[u])
			q.push(u);
	int X = 0;
	while (!q.empty()) {
		int u = q.front(); q.pop();
		int x;
		for (x = 0; b[u][x]; x++);
		if (a[u] % 2) X ^= x;
		for (int v: G[u]) {
			vector<bool> _b = b[v];
			for (int y = 0; y < 1<<14; y++)
				if (b[v][y])
					_b[y ^ x] = true;
			b[v] = _b;
			d[v]--;
			if (!d[v]) q.push(v);
		}
	}
	cout << (X ? 1 : 2) << endl;
}
accuracy: 0.45
time_ms: 20
memory_kb: 4084
final_rank: 2

code_snippet: #include <iostream>
#include <cstdio>
#include <vector>
using namespace std;
#define rep(i,n) for(int i=0;i<(n);++i)
#define pb push_back
vector<int> G[1000];
int g[1000];
void dfs(int v){
	bool is[1001]={};
	for(int u:G[v]){
		if(g[u]<0) dfs(u);
		is[g[u]]=1;
	}
	rep(i,1001) if(!is[i]){
		g[v]=i;
		break;
	}
}
int v[1000],gr[1001];
int main(){
	int N,M;
	cin>>N>>M;
	rep(i,N) cin>>v[i];
	rep(i,M){
		int a,b;
		cin>>a>>b;
		a--,b--;
		G[a].pb(b);
	}
	rep(i,N) g[i]=-1;
	rep(i,N) dfs(i);
	rep(i,N) gr[g[i]]^=v[i];
	bool a=false;
	rep(i,1001) if(gr[i]) a=true;
	if(a) puts("1");
	else puts("2");
}
accuracy: 1
time_ms: 10
memory_kb: 1300
final_rank: 1