QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#335180#7899. Say Hello to the FutureYansuan_HClWA 387ms20872kbC++144.4kb2024-02-22 21:02:462024-02-22 21:02:48

Judging History

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

  • [2024-02-22 21:02:48]
  • 评测
  • 测评结果:WA
  • 用时:387ms
  • 内存:20872kb
  • [2024-02-22 21:02:46]
  • 提交

answer

#include <bits/stdc++.h>
#define ms(x, v) memset(x, v, sizeof(x))
#define il __attribute__((always_inline)) static
#define U(i,l,r) for(int i(l),END##i(r);i<=END##i;++i)
#define D(i,r,l) for(int i(r),END##i(l);i>=END##i;--i)
using namespace std;
using ll = long long;

#define IC isdigit(c)
#define GC c=getchar()
void rd(auto &x) { x = 0; char GC; bool f = 0;
	for (; !IC; GC) f |= c == '-';
	for (; IC; GC) x = x * 10 + c - 48;
	if (f) x = -x;
}
void rd(auto &x, auto &...y) { rd(x); rd(y...); }
#define meow(...) fprintf(stderr, __VA_ARGS__)
#define Assert(e) if (!(e)) { meow("AF@%d\n", __LINE__); exit(__LINE__); }

const int N = 200005; const ll P = 998244353;
void I(ll &x, ll v) { (x += v) %= P; }
int n, a[N];

ll tr[N * 2] {};
void add(int p, ll v) { for (p = max(p, 1); p < N; p += p & -p) tr[p] += v; }
ll query(int p) { ll v = 0;
	for (; p > 0; p ^= p & -p) v += tr[p];
	return v;
}

struct Mx {
	pair<int, int> mx = {1, 0}, sc = {1, 0};
	void check(int v, int p) {
		if (v >= mx.first) sc = mx, mx = {v, p};
		else if (v >= sc.first) sc = {v, p};
	}
	void append(Mx &m, int v, int p) {
		*this = m;
		check(v, p);
	}
};
Mx mR[N], mL[N];
ll f[N], g[N];
ll original = 0, delta[N];


int rk[N];
void solve1(int l, int r) {
	if (l == r) {
		if (a[l] == 1)
			I(f[l], f[l - 1]);
		return;
	}
	int mid((l + r) >> 1);
	solve1(l, mid);

	mR[mid] = mL[mid + 1] = Mx();
	D (i, mid, l)
		mL[i].append(mL[i + 1], a[i], i);
	U (i, mid + 1, r)
		mR[i].append(mR[i + 1], a[i], i);
	U (i, l, r) rk[i] = i;

	sort(rk + l, rk + mid + 1, [&](int u, int v) {
		return mL[u].mx.first + u - 1 < mL[v].mx.first + v - 1;
	});
	int p, i;
	for (p = l, i = mid + 1; i <= r; ++i) {
		while (p <= mid && mL[rk[p]].mx.first + rk[p] - 1 <= i)
			add(rk[p], f[rk[p] - 1]), ++p;
		I(f[i], query(i + 1 - mR[i].mx.first));
	}
	while (--p >= l)
		add(rk[p], P - f[rk[p] - 1]);
	
	solve1(mid + 1, r);
}
void solve2(int l, int r) {
	if (l == r) {
		if (a[l] == 1)
			I(g[l], g[l + 1]);
		return;
	}
	int mid((l + r) >> 1);
	solve2(mid + 1, r);

	mR[mid] = mL[mid + 1] = Mx();
	D (i, mid, l)
		mL[i].append(mL[i + 1], a[i], i);
	U (i, mid + 1, r)
		mR[i].append(mR[i + 1], a[i], i);
	U (i, l, r) rk[i] = i;

	sort(rk + mid + 1, rk + r + 1, [&](int u, int v) {
		return u + 1 - mR[u].mx.first < v + 1 - mR[v].mx.first;
	});
	int p, i;
	for (p = r, i = mid; i >= l; --i) {
		while (p > mid && rk[p] + 1 - mR[rk[p]].mx.first)
			add(n + 1 - rk[p], g[rk[p] + 1]), --p;
		I(g[i], query(n + 1 - (mL[i].mx.first + i - 1)));
	}
	while (++p <= r)
		add(n + 1 - rk[p], P - g[rk[p] + 1]);

	solve2(l, mid);
}
ll h[N];
void recalc(int l, int r) {
	if (l == r) {
		if (a[l] != 1)
			I(delta[l], f[l - 1] * g[r + 1]);
		return;
	}
	int mid((l + r) >> 1);
	// 考虑一个 x 被替换成 1 的影响
	// 若其为前缀最大值,其管辖的一段会被替换成前缀次大值,重算这些点的方案数

	mR[mid] = mL[mid + 1] = Mx();
	D (i, mid, l)
		mL[i].append(mL[i + 1], a[i], i);
	U (i, mid + 1, r)
		mR[i].append(mR[i + 1], a[i], i);
	U (i, l, r) rk[i] = i;

	sort(rk + l, rk + mid + 1, [&](int u, int v) {
		return mL[u].mx.first + u - 1 < mL[v].mx.first + v - 1;
	});
	int p, i;
	for (p = l, i = mid + 1; i <= r; ++i) {
		while (p <= mid && mL[rk[p]].mx.first + rk[p] - 1 <= i)
			add(rk[p], f[rk[p] - 1]), ++p;
		h[i] = (query(i + 1 - mR[i].sc.first) - query(i + 1 - mR[i].mx.first)) * g[i + 1] % P;
	}
	while (--p >= l)
		add(rk[p], P - f[rk[p] - 1]);
	U (i, mid + 1, r)
		I(delta[mR[i].mx.second], h[i]);
	
	sort(rk + mid + 1, rk + r + 1, [&](int u, int v) {
		return u + 1 - mR[u].mx.first < v + 1 - mR[v].mx.first;
	});
	for (p = r, i = mid; i >= l; --i) {
		while (p > mid && rk[p] + 1 - mR[rk[p]].mx.first)
			add(n + 1 - rk[p], g[rk[p] + 1]), --p;
		h[i] = f[i - 1] * (query(n + 1 - (mL[i].sc.first + i - 1)) - query(n + 1 - (mL[i].mx.first + i - 1))) % P;
	}
	while (++p <= r)
		add(n + 1 - rk[p], P - g[rk[p] + 1]);
	D (i, mid, l)
		I(delta[mL[i].mx.second], h[i]);
	
	recalc(l, mid);
	recalc(mid + 1, r);
}

int main() {
	// freopen("arrebol.in", "r", stdin);
	// freopen("arrebol.out", "w", stdout);

	rd(n);
	U (i, 1, n) rd(a[i]);

	f[0] = g[n + 1] = 1;
	solve1(1, n);
	solve2(1, n);
	clog << f[n] << endl;
	clog << g[1] << endl;
	recalc(1, n);
	U (i, 1, n)
		printf("%lld ", (f[n] + delta[i] + P) % P);
	clog << "#" << original << endl;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 2ms
memory: 14172kb

input:

5
1 3 2 1 2

output:

3 6 3 3 6 

result:

ok 5 tokens

Test #2:

score: -100
Wrong Answer
time: 387ms
memory: 20872kb

input:

200000
15922 15391 11782 4758 1973 19909 16800 6438 3821 986 18599 2011 338 19886 12401 4169 11143 12665 3230 12565 15065 15056 5090 16908 13677 12634 11435 1425 8647 3876 10694 12256 3853 19901 5723 11065 6147 13613 13768 15794 14993 5819 8117 13871 14708 15099 7152 9810 14438 10557 3209 1265 13915...

output:

787693878 557985538 756562867 557985538 557985538 557985538 557985538 557985538 557985538 557985538 557985538 690370424 557985538 557985538 557985538 557985538 557985538 552627830 557985538 557985538 557985538 557985538 557985538 751205159 557985538 557985538 557985538 557985538 557985538 17730578 5...

result:

wrong answer 1st words differ - expected: '157122482', found: '787693878'