Submission #1221809

#TimeUsernameProblemLanguageResultExecution timeMemory
1221809trideserFinancial Report (JOI21_financial)C++20
100 / 100
998 ms35780 KiB
#include <bits/stdc++.h>
using namespace std;

struct Treap {
	Treap* l = nullptr;
	Treap* r = nullptr;
	Treap* parent = nullptr;
	int prio;
	int val;
	int mx;
	int n;
	Treap(int prio, int val, int n) :
		prio(prio),
		val(val),
		n(n),
		mx(n)
	{}
};

Treap* merge(Treap* left, Treap* right) {
	if(left == nullptr)
		return right;
	if(right == nullptr)
		return left;
	int newmx = max(left->mx, right->mx);
	if(left->prio > right->prio) {
		left->r = merge(left->r, right);
		if(left->r != nullptr)
			left->r->parent = left;
		left->mx = newmx;
		return left;
	}
	else {
		right->l = merge(left, right->l);
		if(right->l != nullptr)
			right->l->parent = right;
		right->mx = newmx;
		return right;
	}
}

pair<Treap*, Treap*> split(Treap* treap, int treshold) {
	if(treap == nullptr)
		return make_pair(nullptr, nullptr);
	if(treap -> val <= treshold) {
		Treap* a, *b;
		tie(a, b) = split(treap->r, treshold);
		treap->r = a;
		if(treap->r != nullptr)
			treap->r->parent = treap;
		treap->mx = max(max((treap->l == nullptr ? 0 : treap->l->mx), (treap->r == nullptr ? 0 : treap->r->mx)), treap->n);
		return make_pair(treap, b);
	}
	else {
		Treap* a,*b;
		tie(a, b) = split(treap->l, treshold);
		treap->l = b;
		if(treap->l != nullptr)
			treap->l->parent = treap;
		treap->mx = max(max((treap->l == nullptr ? 0 : treap->l->mx), (treap->r == nullptr ? 0 : treap->r->mx)), treap->n);
		return make_pair(a, treap);
	}
}
Treap* remove(Treap* root, Treap* node) {
	if(node == root) {
		return merge(node->l, node->r);
	}
	if(node->parent->l == node) {
		node->parent->l = merge(node->l, node->r);
		if(node->parent->l != nullptr)
			node->parent->l->parent = node->parent;
	}
	else {
		node->parent->r = merge(node->l, node->r);
		if(node->parent->r != nullptr)
			node->parent->r->parent = node->parent;
	}
	node->parent->mx = max(max((node->parent->l == nullptr ? 0 : node->parent->l->mx), (node->parent->r == nullptr ? 0 : node->parent->r->mx)), node->parent->n);
	return root;
}

void print(Treap* t) {
	if(t == nullptr)
		return;
	//print(t->l);
	//cout << " " << (t->parent == nullptr ? -1 : t->parent->val) << " " << t->val << " " << t->n << " " << t->mx << "\n";
	//print(t->r);
}

int main() {
	mt19937 rng(89);
	int N, D;
	cin >> N;
	cin >> D;
	vector<int> vals(N);
	vector<int> priorities(N);
	for(int i = 0; i < N; i++) {
		cin >> vals[i];
		priorities[i] = i;
	}
	shuffle(priorities.begin(), priorities.end(), rng);
	//for(int i = 0; i < N; i++) {
	//	//cout << priorities[i]<<" ";
	//}
	Treap* active = nullptr;
	Treap* reachable = nullptr;
	int ret = 0;
	vector<Treap*> nodes(N);
	multiset<int> vl;
	for(int i = N - 1; i >= max(N - D - 1, 0); i--) {
		Treap* a, *b;
		tie(a, b) = split(active, vals[i]);
		int mx = (b == nullptr ? 0 : b->mx) + 1;
		// add node
		nodes[i] = new Treap(priorities[i], vals[i], mx);
		active = merge(merge(a, nodes[i]), b);
		vl.insert(vals[i]);
		ret = max(ret, mx);
		////print(active);
	//	//cout << "TREAP:\n";
	//	//print(active);
	}
	////cout << "TREAP:\n";
	////print(active);
	vector<Treap*> othernodes;
	for(int i = N - D - 2; i >= 0; i--) {
		// remove node from active
	//	//cout << "A" << i << "\n";
		int toremove = i + D + 1;
		active = remove(active, nodes[toremove]);
		Treap* a, *b;
		tie(a, b) = split(reachable, vals[toremove]);
		Treap* nnode = new Treap(nodes[toremove]->prio, nodes[toremove]->val, nodes[toremove]->n);
		othernodes.push_back(nnode);
		a = merge(a, nnode);
		reachable = merge(a, b);
		vl.erase(vl.find(vals[toremove]));

		// remove unreachable nodes
		reachable = split(reachable, *vl.begin()).second;
		// find max
		for(auto it = vl.begin(); it != vl.end(); it++) {
			//cout << *it << " ";
		}
		//cout << *(vl.begin()) << "LL" << toremove << "\n";
		//cout << "\nACTIVE:\n";
		//print(active);
		//cout << "REACHABLE:\n";
		//print(reachable);
		tie(a, b) = split(active, vals[i]);
		Treap *c, *d;
		tie(c, d) = split(reachable, vals[i]);
		//cout << "MX: " << (d == nullptr ? 0 : d->mx) << " " << (b == nullptr ? 0 : b->mx) << "\n";
		int mx = max((d == nullptr ? 0 : d->mx), (b == nullptr ? 0 : b->mx)) + 1;
		// add node
		nodes[i] = new Treap(priorities[i], vals[i], mx);
		active = merge(merge(a, nodes[i]), b);
		reachable = merge(c, d);
		//cout << "N: " << mx << "\n";
		ret = max(ret, mx);
		vl.insert(vals[i]);
	}
	////cout << ret;
	cout << ret;
	for(Treap* node : nodes)
		delete node;
	for(Treap* node : othernodes)
		delete node;
	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...