This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
/*
Templete by norman/KNN-07
Who tf even love CP :sob:
*/
#ifndef LOCAL
#pragma GCC optimize("Ofast,unroll-loops,inline")
// Bitwise pragma fuck
// #pragma GCC target("avx,avx2,bmi")
// Judges with GCC >= 12 only needs Ofast
// #pragma GCC optimize("O3,no-stack-protector,fast-math,unroll-loops,tree-vectorize")
// MLE optimization
// #pragma GCC optimize("conserve-stack")
// Old judges
// #pragma GCC target("sse4.2,popcnt,lzcnt,abm,mmx,fma,bmi,bmi2")
// New judges. Test with assert(__builtin_cpu_supports("avx2"));
// #pragma GCC target("arch=skylake")
// Atcoder
// #pragma GCC target("avx2,popcnt,lzcnt,abm,bmi,bmi2,fma")
#endif
#ifndef LOCAL
#include "game.h"
#endif
#include <bits/stdc++.h>
using namespace std;
// Wish you can debug? YesYes
#ifndef LOCAL
#define cerr \
if (0) \
cerr
#endif
// Policy based DS?
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
// using namespace __gnu_pbds;
// Who tf deal with overflow
// #define int long long
/*
pbds blog :
https://codeforces.com/blog/entry/11080
https://codeforces.com/blog/entry/13279
*/
// Useful pbds
// template <typename T>
// using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
// template <typename T>
// using ordered_multiset = tree<T, null_type, less_equal<T>, rb_tree_tag, tree_order_statistics_node_update>;
// typedef trie<string, null_type, trie_string_access_traits<>, pat_trie_tag, trie_prefix_search_node_update> pref_trie;
#define el '\n'
#define mpp make_pair
#define pb push_back
#define ppb pop_back
#define pf push_front
#define emp emplace_back
#define fi first
#define nd second
#define forinc(i, a, b) for (int i = (a); i <= (b); i++)
#define fordec(i, a, b) for (int i = (a); i >= (b); i--)
#define alle(x) (x).begin(), (x).end()
#define ralle(x) (x).rbegin(), (x).rend()
#define mms(a, v) memset(a, v, sizeof(a))
#define lwb(a, v) lower_bound((a).begin(), (a).end(), v)
#define upb(a, v) upper_bound((a).begin(), (a).end(), v)
#define bit(i, a) (((a) >> (i)) & 1)
#define BIT_SET(a, b) ((a) |= (1ULL << (b)))
#define BIT_CLEAR(a, b) ((a) &= ~(1ULL << (b)))
#define BIT_FLIP(a, b) ((a) ^= (1ULL << (b)))
#define BIT_CHECK(a, b) (!!((a) & (1ULL << (b))))
#define BITMASK_SET(x, mask) ((x) |= (mask))
#define BITMASK_CLEAR(x, mask) ((x) &= (~(mask)))
#define BITMASK_FLIP(x, mask) ((x) ^= (mask))
#define BITMASK_CHECK_ALL(x, mask) (!(~(x) & (mask)))
#define BITMASK_CHECK_ANY(x, mask) ((x) & (mask))
#define POPCNT(mask) __builtin_popcount(mask)
#define POPCNTLL(mask) __builtin_popcountll(mask)
#define CTZ(mask) __builtin_ctz(mask)
#define CTZLL(mask) __builtin_ctzll(mask)
typedef long long ll;
typedef unsigned long long ull;
typedef long double ldb;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef map<int, int> mii;
typedef map<ll, ll> mll;
typedef vector<bool> vb;
template <typename T, typename U>
inline void maximize(T &x, U y)
{
if (y < x)
x = y;
}
template <typename T, typename U>
inline void minimize(T &x, U y)
{
if (x < y)
x = y;
}
inline int add_m(int a, int b, int mod)
{
int res = a + b;
return (res >= mod ? res - mod : res);
}
inline int mod_neg(int a, int b, int mod)
{
int res;
if (abs(a - b) < mod)
res = a - b;
else
res = (a - b) % mod;
return (res < 0 ? res + mod : res);
}
inline int mul_wmod(int a, int b, int c)
{
ll res = (ll)a * b;
return (res >= c ? res % c : res);
}
inline int mul_wnmod(int a, int b, int c)
{
ll res = (ll)a * b;
return ((res % c) + c) % c;
}
// Debugger Utils
template <typename A, typename B>
ostream &operator<<(ostream &os, const pair<A, B> &p) { return os << '(' << p.first << ", " << p.second << ')'; }
template <size_t i, class T>
ostream &print_tuple_utils(ostream &out, const T &tup)
{
if constexpr (i == tuple_size<T>::value)
return out << ")";
else
return print_tuple_utils<i + 1, T>(out << (i ? ", " : "(") << get<i>(tup), tup);
}
template <class... U>
ostream &operator<<(ostream &out, const tuple<U...> &t)
{
return print_tuple_utils<0, tuple<U...>>(out, t);
}
#define db(val) "[" #val " = " << (val) << "] "
// End if debugger utils
namespace Hasher
{
struct custom_hash
{
static uint32_t splitmix64(uint32_t x)
{
x += 0x9e3779b97f4a7c15;
x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
return x ^ (x >> 31);
}
size_t operator()(uint64_t x) const
{
static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
return splitmix64(x + FIXED_RANDOM);
}
};
struct hash_pair
{
template <class T1, class T2>
size_t operator()(const pair<T1, T2> &p) const
{
auto hash1 = custom_hash{}(p.first);
auto hash2 = custom_hash{}(p.second);
if (hash1 != hash2)
return hash1 ^ hash2;
return hash1;
}
};
struct hash_pair_pair
{
template <class T1, class T2>
size_t operator()(const pair<T1, T2> &p) const
{
auto hash1 = custom_hash{}(p.first);
auto hash2 = hash_pair{}(p.second);
if (hash1 != hash2)
return hash1 ^ hash2;
return hash1;
}
};
}
using namespace Hasher;
const string taskname = "game";
const bool tc = false;
const int oo = 1e9, mod = 1e9 + 7;
const int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};
const ll ool = 1e18;
const ldb eps = 1e-6;
const int MAXN = 1e6;
/**
* Author: normankr07
* Problem: IOI 2013 - GAME
* Submission links: https://oj.uz/problem/view/IOI13_game
* Editorial links: ?
* Algorithm: 2D Sparse Segment Tree
* Notes: I didnt fixed it but anw did i asked
*/
// Approach: 2D Sparse Segment Tree
const int MAXR = 1e9;
const int MAXC = 1e9;
long long gcd2(long long X, long long Y)
{
if (X == 0 || Y == 0)
{
return X + Y;
}
long long tmp;
while (X != Y && Y != 0)
{
tmp = X;
X = Y;
Y = tmp % Y;
}
return X;
}
struct l2_node
{
int ml, mr;
l2_node *lft, *rht;
ll val;
l2_node(int l, int r) : ml(l), mr(r), lft(NULL), rht(NULL), val(1) {}
};
struct l1_node
{
l1_node *lft, *rht;
l2_node l2;
l1_node() : lft(NULL), rht(NULL), l2(0, MAXC) {}
};
static l1_node root;
static void update2(l2_node *node, int q, int k)
{
int tl = node->ml, tr = node->mr;
// Update leaf node
int tm = (tl + tr) >> 1;
if (tl + 1 == tr)
{
node->val = k;
return;
}
l2_node *&curt = (q < tm) ? node->lft : node->rht;
if (curt == NULL)
{
// Make new leaf node, contain the query value
curt = new l2_node(q, q + 1);
curt->val = k;
}
else if (curt->ml <= q && q < curt->mr)
{
// If the node already exist and contain our query point, do update
update2(curt, q, k);
}
else
{
// Travese until the half contain the query node and current node differ;
do
{
(q < tm ? tr : tl) = tm;
tm = (tl + tr) >> 1;
} while ((q < tm) == (curt->ml < tm));
// Make new node and continue to update
l2_node *nnd = new l2_node(tl, tr);
(curt->ml < tm ? nnd->lft : nnd->rht) = curt;
curt = nnd;
update2(nnd, q, k);
}
node->val = gcd2((node->lft ? node->lft->val : 0),
(node->rht ? node->rht->val : 0));
}
ll query2(l2_node *node, int l, int r)
{
if (node == NULL || r <= node->ml || node->mr <= l)
return 0;
else if (l <= node->ml && node->mr <= r)
return node->val;
return gcd2(query2(node->lft, l, r), query2(node->rht, l, r));
}
static void update1(l1_node *node, int l, int r,
int p, int q, int k)
{
int tm = (l + r) >> 1;
if (l + 1 == r)
update2(&node->l2, q, k);
else
{
l1_node *&curt = p < tm ? node->lft : node->rht;
(p < tm ? r : l) = tm;
if (curt == NULL)
curt = new l1_node();
update1(curt, l, r, p, q, k);
k = gcd2((node->lft ? query2(&node->lft->l2, q, q + 1) : 0),
(node->rht ? query2(&node->rht->l2, q, q + 1) : 0));
update2(&node->l2, q, k);
}
}
int query1(l1_node *node, int l, int r, int ax, int ay, int bx, int by)
{
if (node == NULL || ay <= l || r <= ax)
return 0;
else if (ax <= l && r <= ay)
return query2(&node->l2, bx, by);
int tm = (l + r) >> 1;
return gcd2(query1(node->lft, l, tm, ax, ay, bx, by),
query1(node->rht, tm, r, ax, ay, bx, by));
}
// Original Function
void init(int R, int C)
{
}
void update(int P, int Q, long long K)
{
update1(&root, 0, MAXR, P, Q, K);
}
long long calculate(int P, int Q, int U, int V)
{
return query1(&root, 0, MAXR, P, U + 1, Q, V + 1);
// return 42;
}
#ifdef LOCAL
void solve()
{
int R, C, N;
int P, Q, U, V;
long long K;
int i, type;
int res;
cin >> R >> C >> N;
init(R, C);
for (i = 0; i < N; i++)
{
cin >> type;
if (type == 1)
{
cin >> P >> Q >> K;
update(P, Q, K);
}
else if (type == 2)
{
cin >> P >> Q >> U >> V;
cout << calculate(P, Q, U, V) << el;
}
else
assert(false);
}
}
int32_t main()
{
if (fopen((taskname + ".inp").c_str(), "r"))
{
freopen((taskname + ".inp").c_str(), "r", stdin);
freopen((taskname + ".out").c_str(), "w", stdout);
}
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
int tsc = 1;
if (tc)
{
cin >> tsc;
}
while (tsc--)
{
solve();
cout << el;
}
cerr << "\n"
<< "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << " s.\n";
}
#endif
#undef int
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |