QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#649917#3083. Bit Operationle0nTL 0ms0kbC++143.6kb2024-10-18 11:29:212024-10-18 11:29:21

Judging History

你现在查看的是最新测评结果

  • [2024-10-18 11:29:21]
  • 评测
  • 测评结果:TL
  • 用时:0ms
  • 内存:0kb
  • [2024-10-18 11:29:21]
  • 提交

answer

#include <bits/stdc++.h>
 
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
 
const int N = 1e6 + 5, mod = 998244353;
int omg[1 << 21], rev[1 << 21];
int a[N], w[N];
int qpow(int x, int y)
{
	int ans = 1;
	while(y)
	{
		if(y & 1)
			ans = (ll)ans * x % mod;
		x = (ll)x * x % mod;
		y >>= 1;
	}
	return ans;
}
void prep(int n)
{
	int i, j, w;
	for(i = 0; i <= n; i++)
	{
		for(j = 1; j < (1 << i); j++)
			rev[(1 << i) + j] = rev[(1 << (i - 1)) + (j >> 1)] | ((j & 1) << (i - 1));
		w = qpow(3, (mod - 1) >> i);
		omg[(1 << i)] = 1;
		for(j = 1; j < (1 << i); j++)
			omg[(1 << i) + j] = (ll)omg[(1 << i) + j - 1] * w % mod;
	}
}
ull tmp[1 << 21];
void ntt(int *A, int n, bool t)
{
	int i, j, k, w;
	for(i = 0; i < (1 << n); i++)
		tmp[i] = A[i];
	for(i = 0; i < (1 << n); i++)
		if(i < rev[(1 << n) + i])
			swap(tmp[i], tmp[rev[(1 << n) + i]]);
	for(i = 0; i < n; i++)
	{
		for(j = 0; j < (1 << n); j += (2 << i))
			for(k = 0; k < (1 << i); k++)
			{
				w = tmp[(1 << i) + j + k] * omg[(2 << i) + k] % mod;
				tmp[(1 << i) + j + k] = tmp[j + k] + mod - w;
				tmp[j + k] = tmp[j + k] + w;
			}
		if(i == n - 1 || i == 15)
			for(j = 0; j < (1 << n); j++)
				tmp[j] %= mod;
	}
	for(i = 0; i < (1 << n); i++)
		A[i] = tmp[i];
	if(t)
	{
		for(i = 1; i < (1 << n); i++)
			if(i < (1 << n) - i)
				swap(A[i], A[(1 << n) - i]);
		w = qpow(1 << n, mod - 2);
		for(i = 0; i < (1 << n); i++)
			A[i] = (ll)A[i] * w % mod;
	}
}
int X[2][2][N], Y[2][2][N], Z[2][2][N];
struct mat
{
	vector<int> c[2][2];
	mat()
	{
		c[0][0].clear();
		c[0][1].clear();
		c[1][0].clear();
		c[1][1].clear();
	}
	void shrink()
	{
		int i, j;
		for(i = 0; i < 2; i++)
			for(j = 0; j < 2; j++)
				while(!c[i][j].empty() && !c[i][j].back())
					c[i][j].pop_back();
	}
	friend mat operator * (mat f, mat g)
	{
		int l = 0, i, j, k, x, s = 0;
		mat h;
		for(i = 0; i < 2; i++)
			for(j = 0; j < 2; j++)
				for(k = 0; k < 2; k++)
					s = max(s, (int)(f.c[i][j].size() + g.c[j][k].size()));
		if(!s)
			return h;
		while(s >> l)
			l++;
		for(i = 0; i < 2; i++)
			for(j = 0; j < 2; j++)
			{
				memset(X[i][j], 0, 4 << l);
				memset(Y[i][j], 0, 4 << l);
				memset(Z[i][j], 0, 4 << l);
				for(k = 0; k < f.c[i][j].size(); k++)
					X[i][j][k] = f.c[i][j][k];
				for(k = 0; k < g.c[i][j].size(); k++)
					Y[i][j][k] = g.c[i][j][k];
				ntt(X[i][j], l, 0);
				ntt(Y[i][j], l, 0);
			}
		for(i = 0; i < 2; i++)
			for(j = 0; j < 2; j++)
				for(k = 0; k < 2; k++)
					for(x = 0; x < (1 << l); x++)
						Z[i][k][x] = (Z[i][k][x] + (ll)X[i][j][x] * Y[j][k][x]) % mod;
		for(i = 0; i < 2; i++)
			for(j = 0; j < 2; j++)
			{
				ntt(Z[i][j], l, 1);
				for(k = 0; k < s; k++)
					h.c[i][j].emplace_back(Z[i][j][k]);
			}
		h.shrink();
		return h;
	}
};
mat work(int l, int r)
{
	int mid = (l + r) >> 1;
	if(l == r)
	{
		mat f;
		int x = qpow(2 * l - 2, mod - 2);
		f.c[0][1].emplace_back(0);
		f.c[0][1].emplace_back((mod - 2 * l + 4ll) * x % mod);
		f.c[1][0].emplace_back(1);
		x = (2 * l - 3ll) * x % mod;
		f.c[1][1].emplace_back(x);
		f.c[1][1].emplace_back(x);
		return f;
	}
	return work(l, mid) * work(mid + 1, r);
}

int main()
{
	prep(20);
	int n, i, ans = 0;
	scanf("%d", &n);
	for(i = 1; i <= n; i++)
		scanf("%d", a + i);
	mat f;
	f.c[0][1].emplace_back(0);
	f.c[0][1].emplace_back(1);
	f = f * work(2, n);
	for(i = 1; i < f.c[0][1].size(); i++)
		if(a[i])
			ans = (ans + f.c[0][1][i]) % mod;
	ans = (ll)ans * qpow(2, n - 1) % mod;
	for(i = 1; i < n; i++)
		ans = (ll)ans * i % mod;
	printf("%d\n", ans);
	return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 0
Time Limit Exceeded

input:

999993
1 0 0 1 1 0 0 1 0 0 1 0 0 1 0 0 0 1 1 0 1 0 0 1 1 1 1 0 1 0 0 0 0 1 0 0 0 0 0 1 1 0 1 1 1 1 0 1 0 0 0 1 0 0 0 0 1 0 1 0 1 0 0 1 1 1 1 0 1 1 0 0 1 0 1 1 1 0 0 1 1 0 1 0 0 0 1 0 1 0 1 0 0 0 0 0 1 1 0 0 1 0 0 0 0 1 0 0 0 1 0 0 0 1 1 0 0 1 0 1 1 0 1 0 0 0 0 1 1 1 1 0 1 0 1 0 0 1 1 0 0 0 0 0 0 1 1...

output:


result: