Submission #964992

#TimeUsernameProblemLanguageResultExecution timeMemory
964992obokamanGame (IOI13_game)C++17
Compilation error
0 ms0 KiB
#include <iostream> using namespace std; #define debug false typedef long long ll; struct Node { Node *l, *r; int x; ll val; int prio; ll gcd; }; struct RowNode { RowNode *l, *r; int x; Node* row; Node* thick_row; int prio; }; Node* row(RowNode* t) { return t ? t->row : nullptr; } Node* thick_row(RowNode* t) { return t ? t->thick_row : nullptr; } // void update(RowNode* t) { // if (t) { // } // } ll gcd(Node* t) { return t ? t->gcd : -1; } ll val(Node* t) { return t ? t->val : -1; } ll gcdrec(ll a, ll b) { return a == 0 ? b : gcdrec(b%a, a); } ll gcd(ll a, ll b) { if (a == -1 || b == -1) return a == -1 ? b : a; return gcdrec(a, b); } Node* init_node(int x, ll val) { Node* t = new Node; t->l = t->r = nullptr; t->x = x; t->val = t->gcd = val; t->prio = rand(); return t; } void update(Node* t) { if (t) { t->gcd = gcd(gcd(gcd(t->l), ll(t->val)), gcd(t->r)); } } void split(Node* t, Node*& l, Node*& r, int x) { if (!t) { l = r = nullptr; } else { if (x < t->x) { r = t; split(t->l, l, t->l, x); } else { l = t; split(t->r, t->r, r, x); } update(t); } } void merge(Node*& t, Node* l, Node* r) { if (!l || !r) { t = l ? l : r; } else { if (l->prio < r->prio) { t = l; merge(t->r, t->r, r); } else { t = r; merge(t->l, l, t->l); } update(t); } } void insert(Node*&t, int x, ll val) { Node* t1, *t2; split(t, t1, t2, x); Node* tx = init_node(x, val); merge(t, t1, tx); merge(t, t, t2); } void print(Node* t) { if (t) { cout << "["; print(t->l); cout << " " << t->x << "|" << t->val << "|" << t->gcd << " "; print(t->r); cout << "]"; } } void print(RowNode* t, int indent = 0) { if (t) { indent+=2; print(t->l, indent); cout << endl; string sp(indent, ' '); cout << sp << "x=" << t->x << endl; cout << sp << "row="; print(t->row); cout << endl << sp << "thickrow="; print(t->thick_row); cout << endl; cout << endl; print(t->r, indent); indent-=2; } } void update(Node*& t, int x, ll val) { Node* t1, *t2, *t3; split(t, t1, t2, x-1); split(t2, t2, t3, x); if (debug) { cout << "Updating:"; print(t2); cout << endl; } if (!t2) t2 = init_node(x, val); else t2->val = t2->gcd = val; merge(t, t1, t2); merge(t, t, t3); } ll gcdRS(Node* t, int R, int S) { Node* t1, *t2, *t3; split(t, t1, t2, R-1); split(t2, t2, t3, S); ll res = gcd(t2); merge(t, t1, t2); merge(t, t, t3); return res; } // gcd([x, \infy)) ll queryR(RowNode* t, int x, int R, int S) { if (debug) { cout << "QueryR: x=" << x << endl; print(t); cout << endl << endl; } if (!t) return -1; else if (x < t->x) return gcd(gcdRS(thick_row(t->r), R, S), gcd(gcdRS(row(t), R, S), queryR(t->l, x, R, S))); else if (x == t->x) return gcd(gcdRS(thick_row(t->r), R, S), gcdRS(row(t), R, S)); else return queryR(t->r, x, R, S); } // gcd((-\infy, x]) ll queryL(RowNode* t, int x, int R, int S) { if (debug) { cout << "QueryL: x=" << x << endl; print(t); cout << endl << endl; } if (!t) return -1; else if (x > t->x) return gcd(gcdRS(thick_row(t->l), R, S), gcd(gcdRS(row(t), R, S), queryL(t->r, x, R, S))); else if (x == t->x) return gcd(gcdRS(thick_row(t->l), R, S), gcdRS(row(t), R, S)); else return queryL(t->l, x, R, S); } // gcd of [P, Q]x[R, S] ll query(RowNode* t, int P, int Q, int R, int S) { if (!t) return -1; if (t->x < P) return query(t->r, P, Q, R, S); else if (t->x > Q) return query(t->l, P, Q, R, S); else { if (debug) { cout << P << "<=" << t->x << "<=" << Q << endl; cout << "Going for QueryR and QueryL" << endl; } return gcd(gcdRS(row(t), R, S), gcd(queryR(t->l, P, R, S), queryL(t->r, Q, R, S))); } } ll find_gcd(Node* t, int Q) { if (!t) return -1; if (t->x == Q) return t->val; else { return find_gcd(Q < t->x ? t->l : t->r, Q); } } void pointUpdateThickrow(RowNode*& t, int Q, ll val) { // We don't need to fully recalculate thickrow, because only x=Q had // changed. Node* t1, *t2, *t3; split(t->thick_row, t1, t2, Q-1); split(t2, t2, t3, Q); ll newval = gcd( find_gcd(thick_row(t->l), Q), gcd( find_gcd(thick_row(t->r), Q), val) ); if (!t2) t2 = init_node(Q, newval); else t2->val = t2->gcd = newval; merge(t->thick_row, t1, t2); merge(t->thick_row, t->thick_row, t3); } RowNode* find(RowNode* t, int P) { if (!t) return nullptr; else if (P < t->x) return find(t->l, P); else if (P > t->x) return find(t->r, P); else return t; } void copy(Node* src, Node*& dst) { if (!src) dst = nullptr; else { dst = new Node; copy(src->l, dst->l); copy(src->r, dst->r); dst->x = src->x; dst->val = src->val; dst->prio = src->prio; dst->gcd = src->gcd; } } Node* join(Node* t1, Node* t2) { Node* t; if (!t1 && !t2) t = nullptr; else if (!t1) copy(t2, t); else if (!t2) copy(t1, t); else { if (t1->prio < t2->prio) swap(t1, t2); t = new Node; Node* t2l, *t2x, *t2r; split(t2, t2l, t2x, t1->x-1); split(t2x, t2x, t2r, t1->x); t->x = t1->x; // Maybe I don't need t->val for thickrows? t->val = gcd(val(t1), val(t2x)); t->gcd = gcd(gcd(t1), gcd(t2)); t->prio = t1->prio; t->l = join(t1->l, t2l); t->r = join(t1->r, t2r); merge(t2, t2l, t2x); merge(t2, t2, t2r); } return t; } // P in l. void split(RowNode* t, RowNode*& l, RowNode*& r, int P) { if (!t) { l = r = nullptr; } else { if (P < t->x) { t = r; split(t->l, l, t->l, P); } else { t = l; split(t->r, t->r, r, P); } t->thick_row = join(join(thick_row(t->l), t->row), thick_row(t->r)); } } void set_rec(RowNode*& t, int P, int Q, ll val, int prio) { if (!t) { t = new RowNode; t->l = t->r = nullptr; t->x = P; t->row = init_node(Q, val); t->prio = prio; } else { if (prio > t->prio) { // We know (from previous find(...)) that P is not available, we // will insert it here. RowNode* child = t; t = new RowNode; t->x = P; split(child, t->l, t->r, P); t->row = init_node(Q, val); // (Q,val) will be updated as part of updateThickrow t->thick_row = join(thick_row(t->l), thick_row(t->r)); t->prio = prio; } else if (P < t->x) { set_rec(t->l, P, Q, val, prio); } else if (P == t->x) { update(t->row, Q, val); } else { set_rec(t->r, P, Q, val, prio); } } pointUpdateThickrow(t, Q, val); } void set(RowNode*& t, int P, int Q, ll val) { if (find(t, P)) { set_rec(t, P, Q, val, 0); } else { set_rec(t, P, Q, val, rand()); } } RowNode* globalt = nullptr; void init(int R, int C) { // totemo kakkoii } void update(int P, int Q, ll K) { set(globalt, P, Q, K); } ll calculate(int P, int Q, int R, int S) { return query(globalt, P, R, Q, S); } // int main() { int mymain() { RowNode* t = nullptr; string Q; while (cin >> Q) { if (Q == "U") { int P, Q; ll val; cin >> P >> Q >> val; set(t, P, Q, val); } else if (Q == "C") { int P, Q, R, S; cin >> P >> Q >> R >> S; cout << query(t, P, R, Q, S) << endl; } if (debug) { cout << "After:"; print(t); cout << endl; } } return 0; }

Compilation message (stderr)

/usr/bin/ld: /tmp/ccwyPb6E.o: in function `main':
grader.c:(.text.startup+0x6b): undefined reference to `init'
/usr/bin/ld: grader.c:(.text.startup+0xd0): undefined reference to `calculate'
/usr/bin/ld: grader.c:(.text.startup+0x13e): undefined reference to `update'
collect2: error: ld returned 1 exit status