QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#561119#8329. ExcusezhouyuhangAC ✓372ms19456kbC++144.2kb2024-09-12 20:20:412024-09-12 20:20:42

Judging History

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

  • [2024-09-12 20:20:42]
  • 评测
  • 测评结果:AC
  • 用时:372ms
  • 内存:19456kb
  • [2024-09-12 20:20:41]
  • 提交

answer

#include <bits/stdc++.h>
using namespace std;

const int N = 2e5 + 10, P = 998244353;

namespace ModInt {
	inline int add(int x, int y) { return x + y >= P ? x + y - P : x + y;}
	inline int sub(int x, int y) { return x < y ? x - y + P : x - y;}
	inline int mul(int x, int y) { return 1ll * x * y % P;}
	inline int Pow(int x, int y) { int r = 1; for (; y; y >>= 1, x = mul(x, x)) if (y & 1) r = mul(r, x); return r;}
	inline int inv(int x) { return Pow(x, P - 2);}
}
using namespace ModInt;

int n;
int fac[N], ifac[N];
void init(int n) {
	fac[0] = 1;
	for (int i = 1; i <= n; ++i) fac[i] = mul(fac[i - 1], i);
	ifac[n] = inv(fac[n]);
	for (int i = n; i; --i) ifac[i - 1] = mul(ifac[i], i);
}

namespace POLY {
	using Poly = vector<int>;
	int r[1 << 20], len;
	void Init(int n) {
		len = 1; while (len < n) len <<= 1;
		for (int i = 1; i < len; ++i) {
			r[i] = r[i >> 1] >> 1; 
			if (i & 1) r[i] |= (len >> 1);
		}
	}
	Poly G[20];
	void Prework() {
		for (int i = 0; i < 20; ++i) {
			Poly &Gi = G[i]; Gi = Poly(1 << i, 1);
			const int t = Pow(3, P >> i + 1);
			for (int j = 1; j < (1 << i); ++j) Gi[j] = mul(Gi[j - 1], t);
		}		
	}
	void Dft(Poly &a, int type = 1, int n = len) {
		a.resize(n);
		for (int i = 0; i < n; ++i) if (i < r[i]) swap(a[i], a[r[i]]);
		for (int i = 1, o = 0; i < n; i <<= 1, ++o) {
			const Poly Go = G[o];
			for (int j = 0; j < n; j += (i << 1)) {
				for (int k = 0; k < i; ++k) {
					int tx = a[j + k], ty = mul(Go[k], a[i + j + k]);
	                a[j + k] = add(tx, ty), a[i + j + k] = sub(tx, ty);
				}
			}
		}
		if (type == -1) {
			reverse(a.begin() + 1, a.end());
			const int t = inv(n);
			for (int i = 0; i < n; ++i) a[i] = mul(a[i], t);
		}
	}
	Poly operator +(Poly x, Poly y) {
		int tx = x.size(), ty = y.size(); Poly z(max(tx, ty));
		for (int i = 0; i < tx; ++i) z[i] = add(z[i], x[i]);
		for (int i = 0; i < ty; ++i) z[i] = add(z[i], y[i]);
		return z;
	}
	Poly operator -(Poly x, Poly y) {
		int tx = x.size(), ty = y.size(); Poly z(max(tx, ty));
		for (int i = 0; i < tx; ++i) z[i] = add(z[i], x[i]);
		for (int i = 0; i < ty; ++i) z[i] = sub(z[i], y[i]);
		return z;
	}
	Poly operator *(Poly x, Poly y) {
		int tx = x.size(), ty = y.size();
		if (tx <= 50 && ty <= 50) {
			Poly z(tx + ty - 1);
			for (int i = 0; i < tx; ++i) {
				for (int j = 0; j < ty; ++j) {
					z[i + j] = (z[i + j] + 1ll * x[i] * y[j]) % P;
				}
			}
			return z;
		} 
		Init(tx + ty), Dft(x), Dft(y);
		for (int i = 0; i < len; ++i) x[i] = mul(x[i], y[i]);
		Dft(x, -1), x.resize(tx + ty - 1); return x;
	}
	Poly Inv(Poly x) {
		int n = x.size();
		if (n == 1) return {inv(x[0])};
		Poly y = Inv(Poly(x.begin(), x.begin() + (n + 1) / 2));
		Init(n << 1), Dft(x), Dft(y);
		for (int i = 0; i < len; ++i) x[i] = mul(y[i], sub(2, mul(x[i], y[i])));
		Dft(x, -1), x.resize(n);
		return x;
	}
	Poly Der(Poly x) {
		Poly ret(x.size() - 1);
		for (int i = 0; i + 1 < x.size(); ++i) ret[i] = mul(i + 1, x[i + 1]);
		return ret;
	}
	Poly Int(Poly x) {
		Poly ret(x.size() + 1);
		for (int i = 1; i <= x.size(); ++i) ret[i] = mul(mul(ifac[i], fac[i - 1]), x[i - 1]);
		return ret;
	}
	Poly Ln(Poly x) {
		int n = x.size();
		Poly ret = Der(x) * Inv(x); ret.resize(n - 1);
		return Int(ret);
	}
	Poly Exp(Poly x) {
		int n = x.size();
		if (n == 1) return Poly{1};
		Poly y = Exp(Poly(x.begin(), x.begin() + (n + 1) / 2)); y.resize(n);
		x = (x - Ln(y) + Poly{1}) * y, x.resize(n);
		return x;
	}
};
using namespace POLY;

int a[N];

int main() {
 	Prework();

	cin >> n;
	init(n);
	
	Poly f(n);
	for (int i = 0; i < n; ++i) f[i] = ifac[i + 1];
	f = Ln(f);
	for (int i = 1, t = 2; i < n; ++i, t = add(t, t)) f[i] = mul(f[i], inv(t - 1));
	Poly g = Exp(f);
	
	f = f * Poly{-1} + Poly{0, 1};
	Poly h = Exp(f);
	for (int i = 0, x = 1, y = 1; i < n; ++i, x = mul(x, y), y = add(y, y)) h[i] = mul(h[i], x); 
	
	for (int i = 1; i <= n; ++i) a[i] = mul(P + 1 >> 1, add(h[i - 1], a[i - 1]));
	for (int i = 0, x = 1, y = 1; i <= n; ++i, x = mul(x, y), y = mul(y, P + 1 >> 1)) {
		a[i] = mul(a[i], x);
	}
	
	int ans = 0;
	for (int i = 1; i <= n; ++i) ans = add(ans, mul(a[i], g[n - i]));
	ans = mul(ans, fac[n]);
	cout << ans << endl;

	return 0;
}

这程序好像有点Bug,我给组数据试试?

详细

Test #1:

score: 100
Accepted
time: 3ms
memory: 9136kb

input:

1

output:

499122177

result:

ok 1 number(s): "499122177"

Test #2:

score: 0
Accepted
time: 3ms
memory: 9292kb

input:

3

output:

561512450

result:

ok 1 number(s): "561512450"

Test #3:

score: 0
Accepted
time: 7ms
memory: 9128kb

input:

10

output:

609769250

result:

ok 1 number(s): "609769250"

Test #4:

score: 0
Accepted
time: 0ms
memory: 11580kb

input:

1000

output:

475714976

result:

ok 1 number(s): "475714976"

Test #5:

score: 0
Accepted
time: 9ms
memory: 11544kb

input:

1024

output:

178624793

result:

ok 1 number(s): "178624793"

Test #6:

score: 0
Accepted
time: 372ms
memory: 18432kb

input:

100000

output:

537516197

result:

ok 1 number(s): "537516197"

Test #7:

score: 0
Accepted
time: 368ms
memory: 18912kb

input:

99471

output:

489775976

result:

ok 1 number(s): "489775976"

Test #8:

score: 0
Accepted
time: 187ms
memory: 14556kb

input:

65536

output:

171446457

result:

ok 1 number(s): "171446457"

Test #9:

score: 0
Accepted
time: 370ms
memory: 19456kb

input:

84792

output:

371578800

result:

ok 1 number(s): "371578800"

Test #10:

score: 0
Accepted
time: 372ms
memory: 17660kb

input:

93846

output:

841905002

result:

ok 1 number(s): "841905002"

Extra Test:

score: 0
Extra Test Passed