Submission #467935

#TimeUsernameProblemLanguageResultExecution timeMemory
467935LittlePantsFinancial Report (JOI21_financial)C++17
100 / 100
537 ms35836 KiB
#define ll loli
#pragma GCC optimize("Ofast,unroll-loops")
#include<bits/stdc++.h>
#define pb push_back
#define eb emplace_back
#define push emplace
#define sz(x) (int)(x.size())
#define re(x) reverse(all(x))
#define uni(x) x.resize(unique(all(x)) - x.begin())
#define all(x) x.begin(), x.end()
#define mem(x, v) memset(x, v, sizeof x); 
#define pii pair<int, int>
#define inf 1e9
#define INF 1e18
#define mod 1000000007
#define F first
#define S second
#define IO ios_base::sync_with_stdio(0); cin.tie(0);
using namespace std;

const int mxN = 3e5 + 5;
int n, d, a[mxN], dp[mxN], dead[mxN];
priority_queue<pii> pq[mxN], check;

struct BIT{
	int b[mxN];
	inline int qry(int i) {
		int res = 0;
		for (; i > 0; i -= (i&-i)) res = max(res, b[i]);
		return res;
	}
	inline void upd(int i, int v) {
		for (; i <= n; i += (i&-i)) b[i] = max(b[i], v); 
	}
} bit;

#define ls x<<1
#define rs x<<1|1
#define mid ((l+r)>>1)

int seg[mxN * 4];

inline void up(int x) {
	seg[x] = max(seg[ls], seg[rs]);
}

void modify(int p, int v, int l = 1, int r = n, int x = 1) {
	if(l == r) {
		seg[x] = v;
		return;
	}
	if(p <= mid) modify(p, v, l, mid, ls);
	else modify(p, v, mid+1, r, rs);
	up(x);
}

int query(int a, int b, int l = 1, int r = n, int x = 1) {
	if(a <= l and r <= b) return seg[x];
	int res = 0;
	if(a <= mid) res = query(a, b, l, mid, ls);
	if(b > mid) res = max(res, query(a, b, mid+1, r, rs));
	return res;
}

signed main() {
	IO;	
	cin >> n >> d;
	vector<int> tmp;
	for (int i = 1; i <= n; i++) cin >> a[i], tmp.eb(a[i]), pq[i].push(0, inf);
	sort(all(tmp));
	uni(tmp);
	for (int i = 1; i <= n; i++) a[i] = lower_bound(all(tmp), a[i]) - tmp.begin() + 1;
	tmp.clear();

	int ans = 0;
	deque<int> dq;

	for (int i = 1; i <= n; i++) {
		if (i > d + 1) {
			check.push(-a[i - d - 1], - (i - d - 1));
			while (!check.empty()) {
				auto [aa, id] = check.top(); aa = -aa; id = -id;
				int exp = bit.qry(aa);
				if (exp >= i) break;
				check.pop();
				dead[aa] = i - d;
				while (pq[aa].top().S < dead[aa]) pq[aa].pop();
				modify(aa, pq[aa].top().F);
			}
		}
		if (a[i] == 1)  dp[i] = 1;
		else dp[i] = query(1, a[i] - 1) + 1;
		bit.upd(a[i], i + d);

		if (pq[a[i]].top().F < dp[i]) modify(a[i], dp[i]);
		pq[a[i]].push(dp[i], i);
		ans = max(ans, dp[i]);
	}
	cout << ans << '\n';
}
#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...