Submission #597765

# Submission time Handle Problem Language Result Execution time Memory
597765 2022-07-16T20:32:37 Z GusterGoose27 Land of the Rainbow Gold (APIO17_rainbow) C++11
Compilation error
0 ms 0 KB
#include <bits/stdc++.h>

using namespace std;

typedef pair<int, int> pii;

const int MAXN = 2e5+1;
int n, m;
set<int> serp[MAXN];
vector<int> serpy[MAXN];

bool valid(int x, int y) {
	return (serp[x].find(y) != serp[x].end());
}

vector<int> vec_merge(vector<int> &a, vector<int> &b) {
	vector<int> v;
	int l = 0;
	int r = 0;
	while (l < a.size() || r < b.size()) {
		if (l == a.size()) {
			v.push_back(b[r]);
			r++;
			continue;
		}
		if (r == b.size()) {
			v.push_back(a[l]);
			l++;
			continue;
		}
		if (a[l] < b[r]) {
			v.push_back(a[l]);
			l++;
			continue;
		}
		v.push_back(b[r]);
		r++;
	}
	return v;
}

bool right_seam(int x, int y) {
	return valid(x, y) && valid(x, y+1) && valid(x+1, y) && valid(x+1, y+1);
}

bool dubx(int x, int y) {
	return valid(x, y) && valid(x+1, y);
}

bool duby(int x, int y) {
	return valid(x, y) && valid(x, y+1);
}

class intree {
public:
	int lval, rval;
	int ymin, ymax;
	int n;
	intree *l = nullptr;
	intree *r = nullptr;
	int vert_count = 0;
	int u_cut = 0;
	int r_cut = 0;
	int u_sq = 0;
	int r_sq = 0;
	int num_edges = 0;
	int num_sqs = 0;
	int ladj = 0; // edges minus adj nodes
	int radj = 0;
	int uadj = 0;
	int dadj = 0;
	intree(vector<pair<int, vector<int>>> &vals, int lpos, int rpos, int y1, int y2) {
		ymin = y1;
		ymax = y2;
		lval = vals[lpos].first;
		rval = vals[rpos].first;
		n = rpos-lpos+1;
		if (lpos == rpos) special_create(vals[lpos]);
		else {
			int m = (lpos+rpos)/2;
			l = new intree(vals, lpos, m, y1, y2);
			r = new intree(vals, m+1, rpos, y1, y2);
			merge(vals, m);
		}
	}
	void special_create(pair<int, vector<int>> &v) {
		int x = v.first;
		for (int y: v.second) {
			if (valid(x+1, y)) r_cut++;
		}
		if (v.second.back() == ymax) {
			if (valid(x, ymax+1)) u_cut++;
			uadj++;
		}
		if (v.second[0] == ymin) dadj++;
		ladj = radj = v.second.size();
		for (int i = 0; i < v.second.size()-1; i++) {
			if (v.second[i] == v.second[i+1]-1) {
				ladj--;
				radj--;
				num_edges++;
				if (duby(x+1, v.second[i])) r_sq++;
			}
		}
		vert_count = v.second.size();
	}
	void merge(vector<pair<int, vector<int>>> &vals, int m) {
		vert_count = l->vert_count+r->vert_count; //
		num_edges = l->num_edges+r->num_edges+l->r_cut; //
		num_sqs = l->num_sqs+r->num_sqs+l->r_sq; //
		ladj = l->ladj; //
		radj = r->radj; //
		uadj = l->uadj+r->uadj; //
		dadj = l->dadj+r->dadj; //
		u_cut = l->u_cut+r->u_cut; //
		r_cut = r->r_cut; //
		r_sq = r->r_sq; //
		u_sq = l->u_sq+r->u_sq; //
		int xdiv = vals[m].first;
		if (vals[m].first+1 == vals[m+1].first) {
			if (vals[m].second.back() == ymax && vals[m+1].second.back() == ymax) {
				uadj--;
				if (dubx(xdiv, ymax+1)) u_sq++;
			}
			if (vals[m].second[0] == ymin && vals[m+1].second[0] == ymin) dadj--;
		}
	}
	int query(int x1, int x2, int uc, int dc) { // srmask bits go right up left down. Return e-v-sq
		if (lval > x2 || rval < x1) return 0;
		if (lval >= x1 && rval <= x2) {
			int srmask = 2*uc+8*dc;
			if (rval < x2) srmask++;
			if (lval > x1) srmask += 4;
			int s = num_edges-vert_count-num_sqs;
			if (srmask & 1) {
				s += r_cut-r_sq;
			}
			if (srmask & 2) {
				s += u_cut-u_sq;
			}
			if ((srmask & 1) == 0) {
				s += radj;
			}
			if ((srmask & 2) == 0) {
				s += uadj;
			}
			if ((srmask & 4) == 0) {
				s += ladj;
			}
			if ((srmask & 8) == 0) {
				s += dadj;
			}
			if (srmask & 3) s -= right_seam(rval, ymax);
			if ((srmask & 2) && !(srmask & 1)) s -= duby(rval, ymax);
			if (!(srmask & 2) && (srmask & 1)) s -= dubx(rval, ymax);
			if ((srmask & 2) && !(srmask & 4)) s -= duby(lval, ymax);
			if ((srmask & 1) && !(srmask & 8)) s -= dubx(rval, ymin);
			return s;
		}
		return l->query(x1, x2, uc, dc)+r->query(x1, x2, uc, dc);
	}
};

class stree {
public:
	intree *cur_tree;
	int y1, y2;
	stree *l = nullptr;
	stree *r = nullptr;
	vector<pair<int, vector<int>>> vals;
	stree(int dval, int uval) {
		y1 = dval;
		y2 = uval;
		if (y1 == y2) make_vals();
		else {
			int m = (y1+y2)/2;
			l = new stree(dval, m);
			r = new stree(m+1, uval);
			merge_vals();
		}
		if (vals.size() > 0) cur_tree = new intree(vals, 0, vals.size()-1, y1, y2);
	}
	void make_vals() {
		for (int x: serpy[y1]) {
			vals.push_back(pair<int, vector<int>>(x, {y1}));
		}
	}
	void merge_vals() {
		int m1 = l->vals.size();
		int m2 = r->vals.size();
		int a = 0;
		int b = 0;
		while (a < m1 || b < m2) {
			if (a == m1) {
				vals.push_back(r->vals[b]);
				b++;
				continue;
			}
			if (b == m2) {
				vals.push_back(l->vals[a]);
				a++;
				continue;
			}
			if (l->vals[a].first == r->vals[b].first) {
				vals.push_back(pair<int, vector<int>>(l->vals[a].first, vec_merge(l->vals[a].second, r->vals[b].second)));
				a++;
				b++;
				continue;
			}
			if (l->vals[a].first < r->vals[b].first) {
				vals.push_back(l->vals[a]);
				a++;
				continue;
			}
			vals.push_back(r->vals[b]);
			b++;
		}
	}
	int query(int dy, int uy, int x1, int x2) {
		if (cur_tree == nullptr) return 0;
		if (y1 > uy || y2 < dy) return 0;
		if (y1 >= dy && y2 <= uy) {
			int uadj = 0;
			int dadj = 0;
			if (y1 > dy) dadj = 1;
			if (y2 < uy) uadj = 1;
			return cur_tree->query(x1, x2, uadj, dadj);
		}
		return l->query(dy, uy, x1, x2)+r->query(dy, uy, x1, x2);
	}
};

stree *tree;

void color(int r, int c) {
	serp[r].insert(c);
}

void init(int t1, int t2, int sr, int sc, int m, string s) {
	sr--; sc--;
	color(sr, sc);
	for (int i = 0; i < m; i++) {
		if (s[i] == 'N') sr--;
		if (s[i] == 'W') sc--;
		if (s[i] == 'S') sr++;
		if (s[i] == 'E') sc++;
		color(sr, sc);
	}
	for (int x = 0; x < MAXN; x++) {
		for (int y: serp[x]) {
			serpy[y].push_back(x);
		}
	}
	tree = new stree(0, MAXN-1);
}

int colours(int x1, int y1, int x2, int y2) {
	x1--; y1--; x2--; y2--;
	int ans = tree->query(y1, y2, x1, x2);
	if (valid(x1, y1)) ans--;
	if (valid(x1, y2)) ans--;
	if (valid(x2, y1)) ans--;
	if (valid(x2, y2)) ans--;
	return ans+1;
}

int main() {
	init(6, 4, 3, 3, 9, "NWESSWEWS");
	cout << colours(2, 3, 2, 3) << "\n";
	cout << colours(3, 2, 4, 4) << "\n";
	cout << colours(5, 3, 6, 4) << "\n";
	cout << colours(1, 2, 5, 3) << "\n";
	return 0;
}

Compilation message

rainbow.cpp: In function 'std::vector<int> vec_merge(std::vector<int>&, std::vector<int>&)':
rainbow.cpp:20:11: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   20 |  while (l < a.size() || r < b.size()) {
      |         ~~^~~~~~~~~~
rainbow.cpp:20:27: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   20 |  while (l < a.size() || r < b.size()) {
      |                         ~~^~~~~~~~~~
rainbow.cpp:21:9: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   21 |   if (l == a.size()) {
      |       ~~^~~~~~~~~~~
rainbow.cpp:26:9: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   26 |   if (r == b.size()) {
      |       ~~^~~~~~~~~~~
rainbow.cpp: In member function 'void intree::special_create(std::pair<int, std::vector<int> >&)':
rainbow.cpp:97:21: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   97 |   for (int i = 0; i < v.second.size()-1; i++) {
      |                   ~~^~~~~~~~~~~~~~~~~~~
/usr/bin/ld: /tmp/ccc2VpTJ.o: in function `main':
grader.cpp:(.text.startup+0x0): multiple definition of `main'; /tmp/ccTMIXiJ.o:rainbow.cpp:(.text.startup+0x0): first defined here
/usr/bin/ld: /tmp/ccc2VpTJ.o: in function `main':
grader.cpp:(.text.startup+0xed): undefined reference to `init(int, int, int, int, int, char*)'
/usr/bin/ld: grader.cpp:(.text.startup+0x167): undefined reference to `colour(int, int, int, int)'
collect2: error: ld returned 1 exit status