Submission #528738

#TimeUsernameProblemLanguageResultExecution timeMemory
528738d2k05Financial Report (JOI21_financial)C++14
100 / 100
528 ms102096 KiB
#include <bits/stdc++.h>

#define fastio ios_base :: sync_with_stdio(0), cin.tie(0);

using namespace std;
using ll = long long;

const int mxN = 1e6 + 5, mod = 1e9 + 7;

int n, d, a[mxN], K, f[mxN], r[mxN], dp[mxN];
multiset <int> mt[mxN];
vector <int> del[mxN];

int t[mxN * 4];

void Build(int v = 1, int tl = 1, int tr = n) {
	if (tl == tr) 
		t[v] = a[tl];
	else {
		int tm = (tl + tr) / 2;
		Build(v * 2, tl, tm); Build(v * 2 + 1, tm + 1, tr);
		t[v] = min(t[v * 2], t[v * 2 + 1]);
	}
}

int get(int l, int r, int v = 1, int tl = 1, int tr = n) {
	if (l > tr || r < tl)
		return n + 1;
	if (l <= tl && tr <= r)
		return t[v];
	int tm = (tl + tr) / 2;
	return min(get(l, r, v * 2, tl, tm), get(l, r, v * 2 + 1, tm + 1, tr));
}

void Upd(int p, int val) {
	while (p > 0) {
		f[p] = min(f[p], val);
		p = (p & (p + 1)) - 1;
	}
}

int Get(int p) {
	int ans = n + 1;
	while (p <= n) {
		ans = min(ans, f[p]);
		p |= p + 1;
	} 
	return ans;
}

int b[mxN * 4];

void upd(int pos, int val, int v = 1, int tl = 1, int tr = n) {
	if (tl == tr) {
		b[v] = val;
		return;
	}
	int tm = (tl + tr) / 2;
	if (pos <= tm) upd(pos, val, v * 2, tl, tm);
	else upd(pos, val, v * 2 + 1, tm + 1, tr);
	b[v] = max(b[v * 2], b[v * 2 + 1]);
}

int req(int l, int r, int v = 1, int tl = 1, int tr = n) {
	if (l > tr || r < tl)
		return 0;
	if (l <= tl && tr <= r) return b[v];
	int tm = (tl + tr) / 2;
	return max(req(l, r, v * 2, tl, tm), req(l, r, v * 2 + 1, tm + 1, tr));
}

int main() {
	fastio;
	cin >> n >> d;
	for (int i = 1; i <= n; ++i) 
		cin >> a[i], f[i] = n + 1;
	{ 
		vector <int> v;
		for (int i = 1; i <= n; ++i) v.push_back(a[i]);
		sort(v.begin(), v.end());
		for (int i = 1; i <= n; ++i) a[i] = lower_bound(v.begin(), v.end(), a[i]) - v.begin() + 1;
	}
	Build();
	for (int i = n; i > 0; i--) {
		r[i] = Get(a[i] + 1);
		if (i + d - 1 <= n) 
			Upd(get(i, i + d - 1), i + d);
	}
	int ans = 0;
	for (int i = 1; i <= n; ++i) {
		for (auto j : del[i]) {
			mt[a[j]].erase(mt[a[j]].find(dp[j]));
			if (mt[a[j]].empty())
				upd(a[j], 0);
			else
				upd(a[j], *(--mt[a[j]].end()));
		}
		if (a[i] == 1) dp[i] = 1;
		else
			dp[i] = req(1, a[i] - 1) + 1;
		mt[a[i]].insert(dp[i]);		
		upd(a[i], *(--mt[a[i]].end()));
		del[r[i]].push_back(i);
		if (r[i] > n) ans = max(ans, dp[i]);
	}
	cout << ans;
	return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...