QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#108577#6513. Expression 3keainie#TL 2491ms208864kbC++146.1kb2023-05-25 16:16:222023-05-25 16:16:26

Judging History

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

  • [2024-02-14 13:23:19]
  • hack成功,自动添加数据
  • (/hack/531)
  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2023-05-25 16:16:26]
  • 评测
  • 测评结果:TL
  • 用时:2491ms
  • 内存:208864kb
  • [2023-05-25 16:16:22]
  • 提交

answer

// 
#include <bits/stdc++.h>
using namespace std;
#define debug(...) fprintf (stderr, __VA_ARGS__)

typedef long long ll;
typedef __int128 i128;

#define fi first
#define se second
#define lep(i, l, r) for (int i = (l), i##_end = (r); i <= i##_end; ++ i)
#define rep(i, r, l) for (int i = (r), i##_end = (l); i >= i##_end; -- i)

char _c; bool _f; template <class T> inline void IN (T & x) {
	x = 0, _f = 0; while (_c = getchar (), ! isdigit (_c)) if (_c == '-') _f = 1;
	while (isdigit (_c)) x = x * 10 + _c - '0', _c = getchar (); if (_f) x = - x;
}

const int mod = 998244353;
const int inv2 = (mod + 1) >> 1;

inline int mul (int x, int y) { return 1ll * x * y % mod; }
inline int qpow (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 void sub (int &x, int y) { x -= y; if (x < 0) x += mod; }
inline void pls (int &x, int y) { x += y; if (x >= mod) x -= mod; }

inline int dec (int x, int y) { x -= y; if (x < 0) x += mod; return x; }
inline int add (int x, int y) { x += y; if (x >= mod) x -= mod; return x; }

template <class T> inline void chkmin (T & x, T y) { if (x > y) x = y; }
template <class T> inline void chkmax (T & x, T y) { if (x < y) x = y; }

const int N = 2e5 + 5;

int fac[N], ifac[N], inv[N];

inline void init_b (const int L = N - 5) {
	fac[0] = 1; lep (i, 1, L) fac[i] = mul (fac[i - 1], i);
	ifac[L] = qpow (fac[L], mod - 2); rep (i, L, 1) ifac[i - 1] = mul (ifac[i], i);
	inv[1] = 1; lep (i, 2, L) inv[i] = mul (inv[mod % i], mod - mod / i);
}

// {{{ poly

namespace Poly {
	const int Lim = 1 << 20;
	#define Lep(i, l, r) for (int i = (l), i##_end = (r); i < i##_end; ++ i)

	int iv[Lim | 5], w[Lim | 5], _g[Lim | 5];

	inline void init_w () {
		* w = 1, w[1 << 20] = qpow (3, (mod - 1) >> 22);
		rep (i, 20, 1) w[1 << i - 1] = mul (w[1 << i], w[1 << i]);
		Lep (i, 1, Lim) w[i] = mul (w[i & (i - 1)], w[i & ( - i)]);

		iv[1] = 1;
		lep (i, 2, Lim) iv[i] = mul (iv[mod % i], mod - mod / i);
	}

	struct poly {
		int lim;
		vector <int> a;

		inline int size () { return (int) a.size (); }
		inline int & operator [] (const int &x) { return a[x]; }
		inline void clear () { vector <int> ().swap (a); }
		inline void resize (const int &x) { a.resize (lim = x); }

		poly (int n = 0) { resize (lim = n); }
		poly (const vector <int> &o) { a = o, lim = size (); }
		poly (const poly &o) { a = o.a, lim = size (); }

		inline void dif () {
			int s, p, * tw, * tg, * pg;
			for (p = lim >> 1; p; p >>= 1)
				for (tg = _g, tw = w; tg != _g + lim; tg += p << 1, ++ tw)
					for (pg = tg; pg != tg + p; ++ pg)
						s = mul (pg[p], * tw), pg[p] = dec (* pg, s), pls ( * pg, s);
		}
		inline void dit () {
			int s, p, * tw, * tg, * pg;
			for (p = 1; p < lim; p <<= 1)
				for (tg = _g, tw = w; tg != _g + lim; tg += p << 1, ++ tw)
					for (pg = tg; pg != tg + p; ++ pg)
						s = pg[p], pg[p] = mul ( * pg + mod - s, * tw), pls ( * pg, s);
		}

		inline void dft () {
			copy_n (a.begin (), lim, _g), dif ();
			Lep (i, 0, lim) a[i] = _g[i];
		}
		inline void idft () {
			copy_n (a.begin (), lim, _g), dit ();
			for (int iv = mod - (mod - 1) / lim, i = 0; i < lim; ++ i) a[i] = mul (_g[i], iv);
			reverse ( ++ a.begin (), a.end ());
		}
		inline friend poly operator * (poly a, poly b) {
			int n = a.size (), m = b.size (), lim;
			for (lim = 1; lim < n + m - 1; lim <<= 1);
			a.resize (lim), a.dft (), b.resize (lim), b.dft ();
			Lep (i, 0, lim) a[i] = mul (a[i], b[i]);
			return a.idft (), a.resize (n + m - 1), a;
		}

		inline poly inv () {
			poly b (1), c; b[0] = qpow (a[0], mod - 2);
			for (int i = 1; i < lim; i <<= 1) {
				c = a, c.resize (i << 1);
				c.resize (i << 2), c.dft (), b.resize (i << 2), b.dft ();
				Lep (j, 0, i << 2) b[j] = mul (b[j], dec (2, mul (b[j], c[j])));
				b.idft (), b.resize (i << 1);
			}
			return b;
		}

		inline friend void operator -= (poly & a, poly b) {
     	   	int n = b.size();
    	    if (a.size() < n) a.resize (n);
			Lep (i, 0, n) sub (a[i], b[i]);
    	}
		inline friend poly operator / (poly a, poly b) {
			int t = a.size() - b.size() + 1;
			reverse (a.a.begin (), a.a.end ()), a.resize (t);
			reverse (b.a.begin (), b.a.end ()), b.resize (t);
			return a = a * b.inv (), a.resize (t), reverse (a.a.begin (), a.a.end ()), a;
		}
		inline friend poly operator % (poly a, poly b) {
			int n = b.size() - 1;
			if (a.size () <= n) return a;
			return a -= (a / b) * b, a.resize (n), a;
		}
	};
}

using Poly :: init_w;
using Poly :: poly;

// }}}

int n, a[N], b[N];
char str[N];

// {{{ divide

#define lc ((x) << 1)
#define rc ((x) << 1 | 1)
#define mid ((l + r) >> 1)

poly f1[N << 2], f2[N << 2], f3[N << 2];

void init (int x, int l, int r) {
	if (l == r) {
		f3[x].resize (2), f3[x][0] = mod - l, f3[x][1] = 1;

		if (b[l] == -1) {
			f1[x].resize (2), f1[x][0] = mod - l - 1, f1[x][1] = 1;
			f2[x].resize (2), f2[x][0] = mod - l + 1, f2[x][1] = 1;
		} else {
			f1[x].resize (1), f1[x][0] = 1;
			f2[x].resize (2), f2[x][0] = 1;
		}
	} else {
		init (lc, l, mid), init (rc, mid + 1, r);
		f3[x] = f3[lc] * f3[rc];
		f1[x] = f1[lc] * f1[rc];
		f2[x] = f2[lc] * f2[rc];
	}
}

int g1[N], g2[N];
poly h1[N << 2], h2[N << 2];

void divide (int x, int l, int r) {
	if (l == r) {
		h1[x] = h1[x] * f1[x];
		h2[x] = h2[x] * f2[x];

		h1[x] = h1[x] % f3[x];
		h2[x] = h2[x] % f3[x];

		g1[l] = h1[x][0];
		g2[l] = h2[x][0];
	} else {
		h1[x] = h1[x] % f3[x];
		h2[x] = h2[x] % f3[x];

		h1[lc] = h1[x], h1[rc] = h1[x] * f1[lc];
		h2[lc] = h2[x], h2[rc] = h2[x] * f2[lc];
		divide (lc, l, mid), divide (rc, mid + 1, r);
	}
}

#undef lc
#undef rc
#undef mid

// }}}

signed main () {
	init_b (), init_w ();

	IN (n), -- n;
	lep (i, 0, n) IN (a[i]);
	scanf ("%s", str + 1);
	lep (i, 1, n) b[i] = str[i] == '+' ? 1 : -1;

	init (1, 1, n);
	h1[1].resize (1), h1[1][0] = 1;
	h2[1].resize (1), h2[1][0] = 1;
	divide (1, 1, n);

	int ret = a[0];
	lep (i, 1, n) pls (ret, mul (mul (g1[i], qpow (g2[i], mod - 2)), a[i]));
	printf ("%d\n", mul (ret, fac[n]));
	return 0;
}

詳細信息

Test #1:

score: 100
Accepted
time: 31ms
memory: 141936kb

input:

4
9 1 4 1
-+-

output:

46

result:

ok 1 number(s): "46"

Test #2:

score: 0
Accepted
time: 42ms
memory: 139976kb

input:

5
1 2 3 4 5
+-+-

output:

998244313

result:

ok 1 number(s): "998244313"

Test #3:

score: 0
Accepted
time: 2491ms
memory: 208864kb

input:

100000
664815434 205025136 871445392 797947979 379688564 336946672 231295524 401655676 526374414 670533644 156882283 372427821 700299596 166140732 677498490 44858761 185182210 559696133 813911251 842364231 681916958 114039865 222372111 784286397 437994571 152137641 650875922 613727135 209302742 5321...

output:

178167352

result:

ok 1 number(s): "178167352"

Test #4:

score: -100
Time Limit Exceeded

input:

200000
109044620 745578941 396599814 756923982 940933214 875346257 378089839 792684563 491924893 782192923 208569108 421583135 814903710 690275542 15773609 364566266 12890134 661702679 640270667 615999192 13352194 325560419 385152885 265008089 570536451 282429805 331946208 255056541 813809151 150995...

output:


result: