QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#18784#384. 泳池Qingyu100 ✓13ms2012kbC++204.2kb2022-01-26 22:57:532022-05-06 02:35:46

Judging History

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

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2022-05-06 02:35:46]
  • 评测
  • 测评结果:100
  • 用时:13ms
  • 内存:2012kb
  • [2022-01-26 22:57:53]
  • 提交

answer

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const ll MOD = 998244353;
const int PHI = MOD-1, MAX = 2048;

inline int get(int n) {
	int N = 1;
	while (N < n) N <<= 1;
	return N;
}

inline ll pow(ll x, int k) {
	ll a = 1;
	do{ if (k & 1) a = a * x %MOD;
		x = x * x %MOD;
	} while (k >>= 1);
	return a;
}
inline ll Inv(ll a) {return pow(a, PHI-1);}

ull w0[MAX], w1[MAX];
void init(int N) {
	ull W[24];
	W[22] = pow(3ll, PHI>>23);
	for (int i = 22; i; i--)
		W[i-1] = W[i] * W[i] %MOD;
	ull *w = w0, *w_ = W;
	for (int d = 1; d < N; d <<= 1, w_++) {
		ull x = *w++ = 1;
		for (int i = d; --i;)
			*w++ = x = x * *w_ %MOD;
	}
	W[22] = pow((MOD+1)/3, PHI>>23);
	for (int i = 22; i; i--)
		W[i-1] = W[i] * W[i] %MOD;
	w = w1; w_ = W;
	for (int d = 1; d < N; d <<= 1, w_++) {
		ull x = *w++ = 1;
		for (int i = d; --i;)
			*w++ = x = x * *w_ %MOD;
	}
}

#define DFT(A,N) FFT<1>((ull*)(A),N,w0)
#define IDFT(A,N) FFT<0>((ull*)(A),N,w1)
template <bool flag>
void FFT(ull A[], int N, ull *w) {
	const ull MOD = ::MOD, MOD2 = (MOD-1)*MOD;
	for (int i = 1, j = N>>1; i < N; i++) {
		if (i < j) swap(A[i], A[j]);
		A[i] += MOD * 200000000;
		for (int k = N>>1; (j ^= k) < k; k >>= 1);
	}
	for (int d = 1; d < N; d <<= 1)
		for (int i = 0;;) {
			ull tmp = A[i+d] %MOD * *w++;
			A[i+d] = A[i] + MOD2 - tmp;
			A[i] += tmp;
			if (++i & d) {
				if ((i += d) == N) break;
				w -= d;
			}
		}
	if (flag) for (int i = 0; i < N; i++) A[i] %= MOD;
	else {
		ull t = Inv(N);
		for (int i = 0; i < N; i++)
			((A[i] %= MOD) *= t) %= MOD;
	}
}

#define clear(A,n) memset(A,0,(n)<<3)
inline void getDFT(const ll A[], ll a[], int n, int N) {
	clear(copy(A, A+n, a), N-n);
	DFT(a, N);
}
inline void sub(ll *A, const ll *B, int N) {
	while (N--) *A++ -= *B++;
}
inline void mul(ll *A, const ll *B, int N) {
	while (N--) (*A++ *= *B++) %= MOD;
}

ll ta[MAX], tb[MAX], tc[MAX], td[MAX];

void Inv(const ll A[], ll B[], int n) {
	if (n > 58) {
		int m = (n+1)>>1, N = get(n+m-1);
		Inv(A, B, m);
		getDFT(A, ta, n, N);
		getDFT(B, tb, m, N);
		for (int i = 0; i < N; i++)
			(tb[i] *= 2 - ta[i] * tb[i] %MOD) %= MOD;
		IDFT(tb, N);
		copy(tb+m, tb+n, B+m);
	} else {
		*B = Inv(*A);
		for (int i = 1; i < n; i++) {
			ll tot = 0;
			for (int j = 0; j < i; j++)
				tot = (tot + B[j] * A[i-j]) %MOD;
			B[i] = -tot * *B %MOD;
		}
	}
}

namespace Poly_Mod {
	int m, n, d, N;
	//(2m-1) mod (m+1) = div (m-1) rem m
	void setMod(const ll B[], int _m) {
		m = _m; d = m-1; n = m+d; N = get(n);
		reverse_copy(B+2, B+m+1, tc);
		Inv(tc, td, d);
		clear(td+d, N-d);
		DFT(td, N);
		getDFT(B, ta, m+1, N);
	}
	void Mod(ll A[]) {
		reverse_copy(A+m, A+n, tb);
		clear(tb+d, N-d);
		DFT(tb, N);
		mul(tb, td, N);
		IDFT(tb, N);
		reverse(tb, tb+d);
		clear(tb+d, N-d);
		DFT(tb, N);
		mul(tb, ta, N);
		IDFT(tb, N);
		sub(A, tb, n);
	}
}

ll F[MAX], Q[MAX/2], P[MAX];

inline void nextP(int i) {
	ll tmp = P[i-1];
	while (--i) P[i] = (P[i-1] - tmp * Q[i]) %MOD;
	P[0] = tmp * -Q[0] %MOD;
}
inline ll getF(int i) {
	ll res = 0;
	while (i--) res = (res + P[i] * F[i]) % MOD;
	return res;
}

void LinearRec(int m, int n) {
	using namespace Poly_Mod;
	setMod(Q, m);
	clear(P, N);
	int t = 0;
	while (n>>t >= m) t++;
	P[n>>t] = 1;
	while (t--) {
		DFT(P, N);
		mul(P, P, N);
		IDFT(P, N);
		Mod(P);
		if (n>>t & 1) nextP(m);
	}
}

ll Solve(int n, int K, ll p, ll q) {
	clear(F, MAX);
	clear(Q, MAX/2);
	F[0] = Q[0] = 1;
	int m = 1;
	for (int i = K; ~i; i--) {
		ll pw = 1;
		for (int i = 0; i < m; i++, pw = pw * q %MOD)
			Q[i+1] = -p * ((F[i] *= pw) %= MOD) %MOD;
		int m1 = i ? K/i+1 : m+1, N = get(m1+m);
		Inv(Q, P, m = m1);
		clear(P+m, N-m);
		DFT(P, N);
		DFT(F, N);
		mul(F, P, N);
		IDFT(F, N);
		clear(F+m, N-m);
	}
	reverse(Q, Q+1+m);
	LinearRec(m, n);
	return getF(m);
}

int main() {
	int n, K; ll p, q;
	scanf("%d%d%lld%lld",&n,&K,&p,&q);
	q = p * Inv(q) %MOD;
	p = MOD+1 - q;
	if (n != 1) {
		init(get(K+2)<<1);
		printf("%lld\n",(Solve(n,K,p,q) - Solve(n,K-1,p,q) +MOD*2)%MOD);
	} else printf("%lld\n",pow(q, K) * p %MOD);
	return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 5
Accepted
time: 1ms
memory: 1808kb

input:

1 949 139078994 990651604

output:

330219622

result:

ok single line: '330219622'

Test #2:

score: 5
Accepted
time: 0ms
memory: 1816kb

input:

1 944 145496294 755116222

output:

930631836

result:

ok single line: '930631836'

Test #3:

score: 5
Accepted
time: 1ms
memory: 1784kb

input:

10 8 144842939 146358488

output:

375036401

result:

ok single line: '375036401'

Test #4:

score: 5
Accepted
time: 1ms
memory: 1828kb

input:

10 9 147875518 748368567

output:

709619968

result:

ok single line: '709619968'

Test #5:

score: 5
Accepted
time: 1ms
memory: 1772kb

input:

10 10 149567138 375202482

output:

38319127

result:

ok single line: '38319127'

Test #6:

score: 5
Accepted
time: 0ms
memory: 1764kb

input:

947 7 151913594 368520363

output:

141204133

result:

ok single line: '141204133'

Test #7:

score: 5
Accepted
time: 0ms
memory: 1828kb

input:

987 8 153223269 950558887

output:

846391446

result:

ok single line: '846391446'

Test #8:

score: 5
Accepted
time: 1ms
memory: 1760kb

input:

970 9 154292819 361838243

output:

181568951

result:

ok single line: '181568951'

Test #9:

score: 5
Accepted
time: 2ms
memory: 1764kb

input:

980 97 156846631 527638170

output:

20802473

result:

ok single line: '20802473'

Test #10:

score: 5
Accepted
time: 2ms
memory: 1820kb

input:

966 98 157883413 937194648

output:

179742710

result:

ok single line: '179742710'

Test #11:

score: 5
Accepted
time: 0ms
memory: 2012kb

input:

967 99 159400444 542443155

output:

238231981

result:

ok single line: '238231981'

Test #12:

score: 5
Accepted
time: 5ms
memory: 1828kb

input:

989 948 161746901 535761035

output:

876635506

result:

ok single line: '876635506'

Test #13:

score: 5
Accepted
time: 2ms
memory: 1768kb

input:

942 978 162609094 923732105

output:

236028500

result:

ok single line: '236028500'

Test #14:

score: 5
Accepted
time: 5ms
memory: 1780kb

input:

982 942 141042310 163263932

output:

741489934

result:

ok single line: '741489934'

Test #15:

score: 5
Accepted
time: 1ms
memory: 1960kb

input:

999971965 10 166090637 328362110

output:

412492049

result:

ok single line: '412492049'

Test #16:

score: 5
Accepted
time: 1ms
memory: 1772kb

input:

999975613 10 167334775 910367865

output:

8045707

result:

ok single line: '8045707'

Test #17:

score: 5
Accepted
time: 0ms
memory: 1772kb

input:

999975485 96 168371557 321679990

output:

549861210

result:

ok single line: '549861210'

Test #18:

score: 5
Accepted
time: 2ms
memory: 1820kb

input:

999980766 100 77923439 169888588

output:

278412314

result:

ok single line: '278412314'

Test #19:

score: 5
Accepted
time: 13ms
memory: 1832kb

input:

999993900 993 170990906 487479917

output:

265726301

result:

ok single line: '265726301'

Test #20:

score: 5
Accepted
time: 9ms
memory: 1964kb

input:

999974266 969 172060456 897003626

output:

219439784

result:

ok single line: '219439784'

Extra Test:

score: 0
Extra Test Passed