Cod sursa(job #2940932)

Utilizator redstonegamer22Andrei Ion redstonegamer22 Data 16 noiembrie 2022 19:40:02
Problema Cutii Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.19 kb
// Solutie SCLM2 cu Arbore indexat binar
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <map>
#include <cstring>

using namespace std;

#define LOCAL
#ifndef LOCAL
ifstream in("cutii.in");
ofstream out("cutii.out");
#define cin in
#define cout out
#endif // LOCAL

const int NMAX = 3500 + 7; // AIB 2D (WOW!)
int aib[NMAX][NMAX]; // AIB de maxime pe prefix

// pair<int, int> -> <0, 1>, <0, 1>, <0, 2> ...
// update(poz = 2, val = x) -> <0, 1>, <0, 1>, <x, 2> ...

// index[i] = AIB, care retine pe segmentul reprezentat de valoarea aib[i] la ce index se afla maximul
// initial vec[1] = vec[2] = ... = vec[NMAX] = 0

int lsb(int i) { return i & (-i); }

void update(int poz1, int poz2, int val) {
	for(int i = poz1; i < NMAX; i += lsb(i)) { // AIB clasic
		for(int j = poz2; j < NMAX; j += lsb(j)) { // AIB 2D
			aib[i][j] = max(aib[i][j], val);
		}
	}
}

void reset(int poz1, int poz2) {
	for(int i = poz1; i < NMAX; i += lsb(i)) {
		for(int j = poz2; j < NMAX; j += lsb(j)) {
			aib[i][j] = 0;
		}
	}
}

int query(int poz1, int poz2) { // ne zice maximul dintre {vec[1][1], vec[1][2], vec[1][3], ..., vec[1][poz2]}, {vec[2][1] ... vec[2][poz2]} ... {vec[1][poz2] ... vec[poz1][poz2]}
	int ret = 0;
	for(int i = poz1; i > 0; i -= lsb(i)) { // AIB clasic
		for(int j = poz2; j > 0; j -= lsb(j)) {
			ret = max(aib[i][j], ret);
		}
	}
	return ret;
}

int v1[NMAX], v2[NMAX];
int dp[NMAX];

int main() {
	int n, t; cin >> n >> t;

	for(int test = 0; test < t; test++) {
		// memset(aib, 0, sizeof(aib)); // O(NMAX ^ 2) per test, ceea ce e mult

		vector<pair<int, pair<int, int>>> cutii;
		for(int i = 0; i < n; i++) {
			int x, y, z; cin >> x >> y >> z;
		
			cutii.push_back({x, {-1 * y, -1 * z}});
		}
		sort(cutii.begin(), cutii.end());

		for(int i = 1; i <= n; i++) {
			v1[i] = -1 * cutii[i - 1].second.first;
			v2[i] = -1 * cutii[i - 1].second.second;
		}

		for(int i = 1; i <= n; i++) {
			int query_i = query(v1[i] - 1, v2[i] - 1); // ATENTIE, v[i] - 1 => strict crescator si v[i] => crescator
			dp[i] = query_i + 1;

			update(v1[i], v2[i], dp[i]); // vec[v[i]] = dp[i]
		}
	
		cout << query(NMAX - 1, NMAX - 1) << '\n';

		for(int i = 1; i <= n; i++) {
			reset(v1[i], v2[i]);
		}
	}

}