Submission #414845

#TimeUsernameProblemLanguageResultExecution timeMemory
414845KoDGame (IOI13_game)C++17
100 / 100
8599 ms54124 KiB
#include <bits/stdc++.h> #include "game.h" using ll = long long; using ull = unsigned long long; template <class T> using Vec = std::vector<T>; template <class T> using Box = std::unique_ptr<T>; ull xorshift() { static ull val = 7511168; val ^= val >> 7; val ^= val << 9; return val; } struct Node; using Ptr = Box<Node>; struct Node { int pos, size; ull val, gcd; Ptr left, right; Node(const int p, const ull v): pos(p), size(1), val(v), gcd(v), left(), right() {} void fetch() { size = (left ? left->size : 0) + 1 + (right ? right->size : 0); gcd = val; if (left) gcd = std::gcd(gcd, left->gcd); if (right) gcd = std::gcd(gcd, right->gcd); } }; Ptr merge(Ptr x, Ptr y) { if (!x) return y; if (!y) return x; if (xorshift() % (x->size + y->size) < x->size) { x->right = merge(std::move(x->right), std::move(y)); x->fetch(); return x; } else { y->left = merge(std::move(x), std::move(y->left)); y->fetch(); return y; } } std::pair<Ptr, Ptr> split(Ptr x, const int p) { if (!x) return {Ptr(), Ptr()}; if (x->pos >= p) { auto [l, r] = split(std::move(x->left), p); x->left = std::move(r); x->fetch(); return {std::move(l), std::move(x)}; } else { auto [l, r] = split(std::move(x->right), p); x->right = std::move(l); x->fetch(); return {std::move(x), std::move(r)}; } } void set(Ptr& x, const int p, const ull v) { auto [l, s] = split(std::move(x), p); auto [t, r] = split(std::move(s), p + 1); x = merge(merge(std::move(l), std::make_unique<Node>(p, v)), std::move(r)); } ull gcd(Ptr& x, const int a, const int b) { auto [l, s] = split(std::move(x), a); auto [t, r] = split(std::move(s), b); const auto ret = (t ? t->gcd : 0); x = merge(merge(std::move(l), std::move(t)), std::move(r)); return ret; } ull gcd(Ptr& x, const int p) { if (!x) return 0; if (x->pos > p) return gcd(x->left, p); if (x->pos < p) return gcd(x->right, p); return x->val; } struct Segtree { struct Data { int left, right, lch, rch; Ptr tree; Data(const int l, const int r): left(l), right(r), lch(-1), rch(-1), tree() {} }; Vec<Data> data; Segtree() = default; Segtree(const int row) { data.emplace_back(0, row); } void assign(const int x, const int y, const ull v) { int u = 0; Vec<int> path; while (data[u].right - data[u].left > 1) { path.push_back(u); const int mid = (data[u].left + data[u].right) / 2; if (x < mid) { if (data[u].lch == -1) { data.emplace_back(data[u].left, mid); data[u].lch = (int) data.size() - 1; } u = data[u].lch; } else { if (data[u].rch == -1) { data.emplace_back(mid, data[u].right); data[u].rch = (int) data.size() - 1; } u = data[u].rch; } } set(data[u].tree, y, v); while (!path.empty()) { u = path.back(); path.pop_back(); const int l = data[u].lch; const int r = data[u].rch; set(data[u].tree, y, std::gcd(l == -1 ? 0 : gcd(data[l].tree, y), r == -1 ? 0 : gcd(data[r].tree, y))); } } void fold(const int l, const int r, const int l2, const int r2, ull& ret, const int u = 0) { if (u == -1 or r <= data[u].left or data[u].right <= l) return; if (l <= data[u].left and data[u].right <= r) { ret = std::gcd(ret, gcd(data[u].tree, l2, r2)); return; } fold(l, r, l2, r2, ret, data[u].lch); fold(l, r, l2, r2, ret, data[u].rch); } }; Segtree seg; void init(int R, int C) { seg = Segtree(R); } void update(int P, int Q, ll K) { seg.assign(P, Q, K); } ll calculate(int P, int Q, int U, int V) { ull ret = 0; seg.fold(P, U + 1, Q, V + 1, ret); return ret; }

Compilation message (stderr)

game.cpp: In function 'Ptr merge(Ptr, Ptr)':
game.cpp:36:42: warning: comparison of integer expressions of different signedness: 'ull' {aka 'long long unsigned int'} and 'int' [-Wsign-compare]
   36 |     if (xorshift() % (x->size + y->size) < x->size) {
      |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~
#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...