Problem:
Score : 300 points

Problem Statement

There are N people, conveniently numbered 1 through N.
They were standing in a row yesterday, but now they are unsure of the order in which they were standing.
However, each person remembered the following fact: the absolute difference of the number of the people who were standing to the left of that person, and the number of the people who were standing to the right of that person.
According to their reports, the difference above for person i is A_i.

Based on these reports, find the number of the possible orders in which they were standing.
Since it can be extremely large, print the answer modulo 10^9+7.
Note that the reports may be incorrect and thus there may be no consistent order.
In such a case, print 0.

Constraints

1≦N≦10^5

0≦A_i≦N-1

Input

The input is given from Standard Input in the following format:

N
A_1 A_2 ... A_N

Output

Print the number of the possible orders in which they were standing, modulo 10^9+7.

Sample Input 1

5
2 4 4 0 2

Sample Output 1

4

There are four possible orders, as follows:

2,1,4,5,3

2,5,4,1,3

3,1,4,5,2

3,5,4,1,2

Sample Input 2

7
6 4 0 2 4 0 2

Sample Output 2

0

Any order would be inconsistent with the reports, thus the answer is 0.

Sample Input 3

8
7 5 1 1 7 3 5 3

Sample Output 3

16

Solution in C (GCC 5.4.1) (judge verdict: Accepted)

#include <limits.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

// 内部定数
#define D_HUMAN_MAX		100000									// 最大人数
#define D_MOD			1000000007								// 除数

// 内部変数
static int si1Abs[D_HUMAN_MAX];									// 絶対値
static int siHCnt;												// 人数

// 内部変数 - テスト用
#ifdef D_TEST
	static int siRes;
	static FILE *szpFpT, *szpFpA;
#endif

// パターン数取得
int
fGetCnt(
)
{
	int i;

	// 絶対値取得
	for (i = 0; i < siHCnt; i++) {
		int liAbs;
#ifdef D_TEST
		fscanf(szpFpT, "%d", &liAbs);
#else
		fscanf(stdin, "%d", &liAbs);
#endif

		// 値チェック
		if (siHCnt % 2 == 0) {			// 偶数
			if (liAbs % 2 == 0) {			// 偶数
				return 0;
			}
		}
		else {							// 奇数
			if (liAbs % 2 == 1) {			// 奇数
				return 0;
			}
		}

		// データ数
		if (si1Abs[liAbs] >= 2) {		// 既に２件あり
			return 0;
		}
		else {
			si1Abs[liAbs]++;
		}
	}

	// 0データチェック
	if (si1Abs[0] >= 2) {			// ２件あり
		return 0;
	}

	// 指数
	int liCnt = siHCnt / 2;

	// パターン数
	int liRet = 1;
	for (i = 0; i < liCnt; i++) {
		liRet *= 2;
		liRet %= D_MOD;
	}

	return liRet;
}

// 実行メイン
int
fMain(
	int piTNo					// <I> テスト番号 1～
)
{
	char lc1Buf[1024], lc1Out[1024];

	// データ初期化
	memset(si1Abs, 0, sizeof(si1Abs));							// 絶対値

	// テストファイルオープン
#ifdef D_TEST
	sprintf(lc1Buf, ".\\Test\\T%d.txt", piTNo);
	szpFpT = fopen(lc1Buf, "r");
	sprintf(lc1Buf, ".\\Test\\A%d.txt", piTNo);
	szpFpA = fopen(lc1Buf, "r");
	siRes = 0;
#endif

	// 人数取得
#ifdef D_TEST
	fgets(lc1Buf, sizeof(lc1Buf), szpFpT);
#else
	fgets(lc1Buf, sizeof(lc1Buf), stdin);
#endif
	sscanf(lc1Buf, "%d", &siHCnt);

	// パターン数取得
	int liCnt = fGetCnt();

	// 結果セット
	sprintf(lc1Out, "%d\n", liCnt);

	// 結果表示
#ifdef D_TEST
	fgets(lc1Buf, sizeof(lc1Buf), szpFpA);
	if (strcmp(lc1Buf, lc1Out)) {
		siRes = -1;
	}
#else
	printf("%s", lc1Out);
#endif

	// テストファイルクローズ
#ifdef D_TEST
	fclose(szpFpT);
	fclose(szpFpA);
#endif

	// テスト結果
#ifdef D_TEST
	if (siRes == 0) {
		printf("OK %d\n", piTNo);
	}
	else {
		printf("NG %d\n", piTNo);
	}
#endif

	return 0;
}

int
main()
{

#ifdef D_TEST
	int i;
	for (i = D_TEST_SNO; i <= D_TEST_ENO; i++) {
		fMain(i);
	}
#else
	fMain(0);
#endif

	return 0;
}