Submission #1323314

#TimeUsernameProblemLanguageResultExecution timeMemory
1323314buzdiGame (IOI13_game)C++20
Compilation error
0 ms0 KiB
#include "game.h"
#include <cstdio>
#include <algorithm>
#include <cstdlib>

using namespace std;

// --- Helper: GCD ---
long long gcd2(long long X, long long Y) {
    long long tmp;
    while (X != 0 && Y != 0) {
        if (X > Y) X %= Y;
        else Y %= X;
    }
    return X + Y;
}

// --- Treap (Y-Dimension) ---
// Standard Treap supporting point update and range GCD query.

struct Treap {
    int key;            // Column index
    int prio;           // Random priority
    long long val;      // Value at this column
    long long gcd_val;  // GCD of the subtree
    Treap *l, *r;

    Treap(int k, long long v) : key(k), prio(rand()), val(v), gcd_val(v), l(NULL), r(NULL) {}
};

// Update the gcd_val of a node based on children
void update_gcd(Treap *t) {
    if (!t) return;
    t->gcd_val = t->val;
    if (t->l) t->gcd_val = gcd2(t->gcd_val, t->l->gcd_val);
    if (t->r) t->gcd_val = gcd2(t->gcd_val, t->r->gcd_val);
}

// Split treap 't' by key 'k' into 'l' (keys <= k) and 'r' (keys > k)
void split(Treap *t, int k, Treap *&l, Treap *&r) {
    if (!t) {
        l = r = NULL;
    } else if (t->key <= k) {
        split(t->r, k, t->r, r);
        l = t;
    } else {
        split(t->l, k, l, t->l);
        r = t;
    }
    update_gcd(t);
}

// Merge treaps 'l' and 'r'
void merge(Treap *&t, Treap *l, Treap *r) {
    if (!l || !r) {
        t = (l ? l : r);
    } else if (l->prio > r->prio) {
        merge(l->r, l->r, r);
        t = l;
    } else {
        merge(r->l, l, r->l);
        t = r;
    }
    update_gcd(t);
}

// Insert or Update a value in the Treap
// If key exists, update value. If not, insert.
void treap_update(Treap *&t, int key, long long val) {
    Treap *t1, *t2, *t3;
    // Split into < key, == key, > key
    split(t, key, t2, t3);       // t2 has <= key
    split(t2, key - 1, t1, t2);  // t1 has < key, t2 has == key
    
    // t2 is now the node with 'key' if it exists, or NULL
    if (t2) {
        t2->val = val;
        update_gcd(t2);
    } else {
        t2 = new Treap(key, val);
    }
    
    // Merge back: t1 + t2 + t3
    merge(t2, t1, t2);
    merge(t, t2, t3);
}

// Query GCD in range [ql, qr] on the Treap
long long treap_query(Treap *t, int ql, int qr) {
    Treap *t1, *t2, *t3;
    // Split to isolate the range [ql, qr]
    split(t, qr, t2, t3);        // t2 <= qr, t3 > qr
    split(t2, ql - 1, t1, t2);   // t1 < ql, t2 is range [ql, qr]
    
    long long res = (t2 ? t2->gcd_val : 0);
    
    // Merge back to restore structure
    merge(t2, t1, t2);
    merge(t, t2, t3);
    
    return res;
}

// Fast point query helper for calculating internal X-nodes
// (Avoids split/merge overhead)
long long treap_get_val(Treap *t, int key) {
    while (t) {
        if (key == t->key) return t->val;
        if (key < t->key) t = t->l;
        else t = t->r;
    }
    return 0;
}

// --- Segment Tree (X-Dimension) ---
// Dynamic Segment Tree on rows.

struct NodeX {
    NodeX *l, *r;
    Treap *rootY; // The Y-dimension structure for this row range
    
    NodeX() : l(NULL), r(NULL), rootY(NULL) {}
};

NodeX *rootX = NULL;
int R_global, C_global;

// Update the 2D structure
// node: current X-node
// nl, nr: current row range
// r, c: target coordinate
// val: new value
void updateX(NodeX *&node, int nl, int nr, int r, int c, long long val) {
    if (!node) node = new NodeX();
    
    // If we are at the exact row (leaf of X-tree)
    if (nl == nr) {
        treap_update(node->rootY, c, val);
        return;
    }
    
    int mid = nl + (nr - nl) / 2;
    if (r <= mid) updateX(node->l, nl, mid, r, c, val);
    else updateX(node->r, mid + 1, nr, r, c, val);
    
    // Update logic for internal nodes:
    // The value at (row_range, c) in the X-tree should be:
    // gcd( value at (left_child, c), value at (right_child, c) )
    long long v1 = (node->l) ? treap_get_val(node->l->rootY, c) : 0;
    long long v2 = (node->r) ? treap_get_val(node->r->rootY, c) : 0;
    
    treap_update(node->rootY, c, gcd2(v1, v2));
}

// Query the 2D structure
long long queryX(NodeX *node, int nl, int nr, int r1, int r2, int c1, int c2) {
    if (!node || nl > r2 || nr < r1) return 0;
    
    // If the X-range is fully within the query range
    if (nl >= r1 && nr <= r2) {
        return treap_query(node->rootY, c1, c2);
    }
    
    int mid = nl + (nr - nl) / 2;
    return gcd2(queryX(node->l, nl, mid, r1, r2, c1, c2),
                queryX(node->r, mid + 1, nr, r1, r2, c1, c2));
}

// --- Interface ---

void init(int R, int C) {
    R_global = R;
    C_global = C;
    srand(2013); // Seed for Treap priorities
    rootX = new NodeX();
}

void update(int P, int Q, long long K) {
    updateX(rootX, 0, R_global - 1, P, Q, K);
}

long long calculate(int P, int Q, int U, int V) {
    return queryX(rootX, 0, R_global - 1, P, U, Q, V);
}#include "game.h"
#include <cstdio>
#include <algorithm>
#include <cstdlib>

using namespace std;

// --- Helper: GCD ---
long long gcd2(long long X, long long Y) {
    long long tmp;
    while (X != 0 && Y != 0) {
        if (X > Y) X %= Y;
        else Y %= X;
    }
    return X + Y;
}

// --- Treap (Y-Dimension) ---
// Standard Treap supporting point update and range GCD query.

struct Treap {
    int key;            // Column index
    int prio;           // Random priority
    long long val;      // Value at this column
    long long gcd_val;  // GCD of the subtree
    Treap *l, *r;

    Treap(int k, long long v) : key(k), prio(rand()), val(v), gcd_val(v), l(NULL), r(NULL) {}
};

// Update the gcd_val of a node based on children
void update_gcd(Treap *t) {
    if (!t) return;
    t->gcd_val = t->val;
    if (t->l) t->gcd_val = gcd2(t->gcd_val, t->l->gcd_val);
    if (t->r) t->gcd_val = gcd2(t->gcd_val, t->r->gcd_val);
}

// Split treap 't' by key 'k' into 'l' (keys <= k) and 'r' (keys > k)
void split(Treap *t, int k, Treap *&l, Treap *&r) {
    if (!t) {
        l = r = NULL;
    } else if (t->key <= k) {
        split(t->r, k, t->r, r);
        l = t;
    } else {
        split(t->l, k, l, t->l);
        r = t;
    }
    update_gcd(t);
}

// Merge treaps 'l' and 'r'
void merge(Treap *&t, Treap *l, Treap *r) {
    if (!l || !r) {
        t = (l ? l : r);
    } else if (l->prio > r->prio) {
        merge(l->r, l->r, r);
        t = l;
    } else {
        merge(r->l, l, r->l);
        t = r;
    }
    update_gcd(t);
}

// Insert or Update a value in the Treap
// If key exists, update value. If not, insert.
void treap_update(Treap *&t, int key, long long val) {
    Treap *t1, *t2, *t3;
    // Split into < key, == key, > key
    split(t, key, t2, t3);       // t2 has <= key
    split(t2, key - 1, t1, t2);  // t1 has < key, t2 has == key
    
    // t2 is now the node with 'key' if it exists, or NULL
    if (t2) {
        t2->val = val;
        update_gcd(t2);
    } else {
        t2 = new Treap(key, val);
    }
    
    // Merge back: t1 + t2 + t3
    merge(t2, t1, t2);
    merge(t, t2, t3);
}

// Query GCD in range [ql, qr] on the Treap
long long treap_query(Treap *t, int ql, int qr) {
    Treap *t1, *t2, *t3;
    // Split to isolate the range [ql, qr]
    split(t, qr, t2, t3);        // t2 <= qr, t3 > qr
    split(t2, ql - 1, t1, t2);   // t1 < ql, t2 is range [ql, qr]
    
    long long res = (t2 ? t2->gcd_val : 0);
    
    // Merge back to restore structure
    merge(t2, t1, t2);
    merge(t, t2, t3);
    
    return res;
}

// Fast point query helper for calculating internal X-nodes
// (Avoids split/merge overhead)
long long treap_get_val(Treap *t, int key) {
    while (t) {
        if (key == t->key) return t->val;
        if (key < t->key) t = t->l;
        else t = t->r;
    }
    return 0;
}

// --- Segment Tree (X-Dimension) ---
// Dynamic Segment Tree on rows.

struct NodeX {
    NodeX *l, *r;
    Treap *rootY; // The Y-dimension structure for this row range
    
    NodeX() : l(NULL), r(NULL), rootY(NULL) {}
};

NodeX *rootX = NULL;
int R_global, C_global;

// Update the 2D structure
// node: current X-node
// nl, nr: current row range
// r, c: target coordinate
// val: new value
void updateX(NodeX *&node, int nl, int nr, int r, int c, long long val) {
    if (!node) node = new NodeX();
    
    // If we are at the exact row (leaf of X-tree)
    if (nl == nr) {
        treap_update(node->rootY, c, val);
        return;
    }
    
    int mid = nl + (nr - nl) / 2;
    if (r <= mid) updateX(node->l, nl, mid, r, c, val);
    else updateX(node->r, mid + 1, nr, r, c, val);
    
    // Update logic for internal nodes:
    // The value at (row_range, c) in the X-tree should be:
    // gcd( value at (left_child, c), value at (right_child, c) )
    long long v1 = (node->l) ? treap_get_val(node->l->rootY, c) : 0;
    long long v2 = (node->r) ? treap_get_val(node->r->rootY, c) : 0;
    
    treap_update(node->rootY, c, gcd2(v1, v2));
}

// Query the 2D structure
long long queryX(NodeX *node, int nl, int nr, int r1, int r2, int c1, int c2) {
    if (!node || nl > r2 || nr < r1) return 0;
    
    // If the X-range is fully within the query range
    if (nl >= r1 && nr <= r2) {
        return treap_query(node->rootY, c1, c2);
    }
    
    int mid = nl + (nr - nl) / 2;
    return gcd2(queryX(node->l, nl, mid, r1, r2, c1, c2),
                queryX(node->r, mid + 1, nr, r1, r2, c1, c2));
}

// --- Interface ---

void init(int R, int C) {
    R_global = R;
    C_global = C;
    srand(2013); // Seed for Treap priorities
    rootX = new NodeX();
}

void update(int P, int Q, long long K) {
    updateX(rootX, 0, R_global - 1, P, Q, K);
}

long long calculate(int P, int Q, int U, int V) {
    return queryX(rootX, 0, R_global - 1, P, U, Q, V);
}

Compilation message (stderr)

game.cpp:184:2: error: stray '#' in program
  184 | }#include "game.h"
      |  ^
game.cpp:184:3: error: 'include' does not name a type
  184 | }#include "game.h"
      |   ^~~~~~~
game.cpp:192:11: error: redefinition of 'long long int gcd2(long long int, long long int)'
  192 | long long gcd2(long long X, long long Y) {
      |           ^~~~
game.cpp:9:11: note: 'long long int gcd2(long long int, long long int)' previously defined here
    9 | long long gcd2(long long X, long long Y) {
      |           ^~~~
game.cpp:204:8: error: redefinition of 'struct Treap'
  204 | struct Treap {
      |        ^~~~~
game.cpp:21:8: note: previous definition of 'struct Treap'
   21 | struct Treap {
      |        ^~~~~
game.cpp:215:6: error: redefinition of 'void update_gcd(Treap*)'
  215 | void update_gcd(Treap *t) {
      |      ^~~~~~~~~~
game.cpp:32:6: note: 'void update_gcd(Treap*)' previously defined here
   32 | void update_gcd(Treap *t) {
      |      ^~~~~~~~~~
game.cpp:223:6: error: redefinition of 'void split(Treap*, int, Treap*&, Treap*&)'
  223 | void split(Treap *t, int k, Treap *&l, Treap *&r) {
      |      ^~~~~
game.cpp:40:6: note: 'void split(Treap*, int, Treap*&, Treap*&)' previously defined here
   40 | void split(Treap *t, int k, Treap *&l, Treap *&r) {
      |      ^~~~~
game.cpp:237:6: error: redefinition of 'void merge(Treap*&, Treap*, Treap*)'
  237 | void merge(Treap *&t, Treap *l, Treap *r) {
      |      ^~~~~
game.cpp:54:6: note: 'void merge(Treap*&, Treap*, Treap*)' previously defined here
   54 | void merge(Treap *&t, Treap *l, Treap *r) {
      |      ^~~~~
game.cpp:252:6: error: redefinition of 'void treap_update(Treap*&, int, long long int)'
  252 | void treap_update(Treap *&t, int key, long long val) {
      |      ^~~~~~~~~~~~
game.cpp:69:6: note: 'void treap_update(Treap*&, int, long long int)' previously defined here
   69 | void treap_update(Treap *&t, int key, long long val) {
      |      ^~~~~~~~~~~~
game.cpp:272:11: error: redefinition of 'long long int treap_query(Treap*, int, int)'
  272 | long long treap_query(Treap *t, int ql, int qr) {
      |           ^~~~~~~~~~~
game.cpp:89:11: note: 'long long int treap_query(Treap*, int, int)' previously defined here
   89 | long long treap_query(Treap *t, int ql, int qr) {
      |           ^~~~~~~~~~~
game.cpp:289:11: error: redefinition of 'long long int treap_get_val(Treap*, int)'
  289 | long long treap_get_val(Treap *t, int key) {
      |           ^~~~~~~~~~~~~
game.cpp:106:11: note: 'long long int treap_get_val(Treap*, int)' previously defined here
  106 | long long treap_get_val(Treap *t, int key) {
      |           ^~~~~~~~~~~~~
game.cpp:301:8: error: redefinition of 'struct NodeX'
  301 | struct NodeX {
      |        ^~~~~
game.cpp:118:8: note: previous definition of 'struct NodeX'
  118 | struct NodeX {
      |        ^~~~~
game.cpp:308:8: error: redefinition of 'NodeX* rootX'
  308 | NodeX *rootX = NULL;
      |        ^~~~~
game.cpp:125:8: note: 'NodeX* rootX' previously defined here
  125 | NodeX *rootX = NULL;
      |        ^~~~~
game.cpp:309:5: error: redefinition of 'int R_global'
  309 | int R_global, C_global;
      |     ^~~~~~~~
game.cpp:126:5: note: 'int R_global' previously declared here
  126 | int R_global, C_global;
      |     ^~~~~~~~
game.cpp:309:15: error: redefinition of 'int C_global'
  309 | int R_global, C_global;
      |               ^~~~~~~~
game.cpp:126:15: note: 'int C_global' previously declared here
  126 | int R_global, C_global;
      |               ^~~~~~~~
game.cpp:316:6: error: redefinition of 'void updateX(NodeX*&, int, int, int, int, long long int)'
  316 | void updateX(NodeX *&node, int nl, int nr, int r, int c, long long val) {
      |      ^~~~~~~
game.cpp:133:6: note: 'void updateX(NodeX*&, int, int, int, int, long long int)' previously defined here
  133 | void updateX(NodeX *&node, int nl, int nr, int r, int c, long long val) {
      |      ^~~~~~~
game.cpp:339:11: error: redefinition of 'long long int queryX(NodeX*, int, int, int, int, int, int)'
  339 | long long queryX(NodeX *node, int nl, int nr, int r1, int r2, int c1, int c2) {
      |           ^~~~~~
game.cpp:156:11: note: 'long long int queryX(NodeX*, int, int, int, int, int, int)' previously defined here
  156 | long long queryX(NodeX *node, int nl, int nr, int r1, int r2, int c1, int c2) {
      |           ^~~~~~
game.cpp:354:6: error: redefinition of 'void init(int, int)'
  354 | void init(int R, int C) {
      |      ^~~~
game.cpp:171:6: note: 'void init(int, int)' previously defined here
  171 | void init(int R, int C) {
      |      ^~~~
game.cpp:361:6: error: redefinition of 'void update(int, int, long long int)'
  361 | void update(int P, int Q, long long K) {
      |      ^~~~~~
game.cpp:178:6: note: 'void update(int, int, long long int)' previously defined here
  178 | void update(int P, int Q, long long K) {
      |      ^~~~~~
game.cpp:365:11: error: redefinition of 'long long int calculate(int, int, int, int)'
  365 | long long calculate(int P, int Q, int U, int V) {
      |           ^~~~~~~~~
game.cpp:182:11: note: 'long long int calculate(int, int, int, int)' previously defined here
  182 | long long calculate(int P, int Q, int U, int V) {
      |           ^~~~~~~~~