Submission #1346947

#TimeUsernameProblemLanguageResultExecution timeMemory
1346947vladmart09Financial Report (JOI21_financial)C++20
19 / 100
3000 ms373612 KiB
#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
#include <random>
#include <queue>
#include <numeric>
#include <array>
#include <iomanip>
#include <stack>
#include <chrono>
#include <climits>

using namespace std;

using ll = long long;
using ld = long double;
using vi = vector<ll>;
using vii = vector<vi>;
using viii = vector<vii>;
using pi = pair<ll, ll>;
using vpi = vector<pi>;
using vb = vector<bool>;
using vs = vector<string>;

#define vec vector
#define cmax(x, y) x = max({x, y})
#define cmin(x, y) x = min({x, y})
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()

const ll N = 3e5 + 5, MOD = 998244353, INF = (ll)1e18, K = 20, B = 836;

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());

ll fen[N];

void add(ll i, ll v) {
	for (; i > 0 && i < N; i -= i & -i) cmin(fen[i], v);
}

ll get(ll i) {
	ll res = INF;

	for (; i > 0 && i < N; i += i & -i) cmin(res, fen[i]);
	return res;
}

struct Seg {
	vector<multiset<ll>> seg;

	Seg(ll n) {
		seg.resize(n * 4);
	}

	void update(ll t, ll tl, ll tr, ll i, ll v, bool add) {
		if (add) {
			seg[t].insert(v);
		}
		else {
			seg[t].erase(seg[t].find(v));
		}

		if (tl == tr) return;
		ll tm = tl + (tr - tl) / 2;
		 
		if (i <= tm) update(t * 2, tl, tm, i, v, add);
		else update(t * 2 + 1, tm + 1, tr, i, v, add);
	}

	ll get(ll t, ll tl, ll tr, ll l, ll r) {
		if (tl > r || tr < l) return 0ll;

		if (l <= tl && tr <= r) {
			if (!seg[t].empty()) return *seg[t].rbegin();
			else return 0ll;
		}

		ll tm = tl + (tr - tl) / 2;

		ll res1 = get(t * 2, tl, tm, l, r);
		ll res2 = get(t * 2 + 1, tm + 1, tr, l, r);

		return max(res1, res2);
	}
};

void solve() {
	ll n, d; cin >> n >> d;
	fill(fen, fen + N, INF);

	vi a(n); for (ll& x : a) cin >> x;

	vi b = a; sort(all(b)); b.erase(unique(all(b)), b.end());

	auto get_idx = [&](ll i) {
		return 1 + lower_bound(all(b), i) - b.begin();
	};

	for (auto& x : a) x = get_idx(x);

	vi w(n);
	multiset<ll> ms;
	for (ll i = n - 1; i >= 0; i--) {
		ms.insert(a[i]);

		if (i + d + 1 < n) {
			ms.erase(ms.find(a[i + d + 1]));
		}

		w[i] = *ms.begin() - 1;
	}

	vi c(n);
	for (ll i = n - 1; i >= 0; i--) {
		add(w[i], i);
		ll res = get(a[i]);

		c[i] = res + d - 1;
	}

	vi dp(n, 0);
	vii end(n); for (ll i = 0; i < n; i++) {
		if (c[i] + 1 < n) end[c[i] + 1].push_back(i);
	}

	Seg* seg = new Seg(n);

	for (ll i = 0; i < n; i++) {
		for (auto& x : end[i]) {
			seg->update(1, 1, n, a[x], dp[x], false);
		}

		dp[i] = seg->get(1, 1, n, 1, a[i] - 1) + 1;
		seg->update(1, 1, n, a[i], dp[i], true);
	}

	ll ans = 0;

	for (ll i = 0; i < n; i++) {
		if (c[i] >= n - 1) cmax(ans, dp[i]);
	}

	cout << ans;
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);

	long long tt = 1;
	//cin >> tt;

	while (tt--) {
		solve();
		cout << '\n';
	}

	return 0;
}

/*



















Какие темы повторить:
1) мст
2) 2сат
3) точки артикуляции
4) ксор базис
5) эйлеровый цикл, путь
6) кмп
7) конвекс хулл
8) вафельное дерево
9) суфиксный массив
10) суффиксный автомат
11) ним

*/
#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...