1. 程式人生 > 其它 >【Codeforces 1513B】AND Sequences

【Codeforces 1513B】AND Sequences

連結:

洛谷

部落格園

題目大意:

\(a\) 有多少排列使得 \(\forall i\in\left[1,n\right)\) ,有 \(\bigwedge\limits_{j=1}^ia_j=\bigwedge\limits_{j=i+1}^na_j\)

思路:

對於 \(i=1\) 的情況,即 \(a_1=\bigwedge\limits_{j=2}^na_j\),可以看出,每個合法的排列至少有兩個數使得它們是整個排列的邏輯和,並且它們都在整個排列的兩端,即 \(1,n\) 兩點。

由此我們可以先找出 \(a\) 的邏輯和在 \(a\) 中的個數 \(m\),答案即 \(\dbinom{n}{m}\times (n-2)!\)

程式碼:

const int N = 2e5 + 10;
const ll mod = 1e9 + 7;

inline ll Read() {
	ll x = 0, f = 1;
	char c = getchar();
	while (c != '-' && (c < '0' || c > '9')) c = getchar();
	if (c == '-') f = -f, c = getchar();
	while (c >= '0' && c <= '9') x = (x << 3) + (x << 1) + c - '0', c = getchar();
	return x * f;
}

int t, n;
ll a[N], cnt;

int main() {
//	freopen(".in", "r", stdin);
//	freopen(".out", "w", stdout);
	for (t = Read(); t--; ) {
		n = Read(); cnt = 0; 
		ll b = (1ll << 32) - 1;
		for (int i = 1; i <= n; i++) a[i] = Read(), b &= a[i];
		for (int i = 1; i <= n; i++)
			if (a[i] == b) cnt++;
		if (cnt <= 1) { puts("0"); continue; }
		ll ans = cnt * (cnt - 1) % mod;
		for (int i = 1; i <= n - 2; i++) ans = ans * i % mod;
		printf ("%lld\n", ans);
	}
	return 0;
}