Submission #1322204

#TimeUsernameProblemLanguageResultExecution timeMemory
1322204ro9669게임 (IOI13_game)C++20
100 / 100
5653 ms56884 KiB
#include "game.h" #include <bits/stdc++.h> using namespace std; int n , m; mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); void init(int _n , int _m){ n = _n; m = _m; srand(time(NULL)); } struct Node{ Node *left , *right; int pos; long long val , gcd_sum , prio; Node(){}; Node(int _pos , long long _val){ left = right = nullptr; pos = _pos; val = gcd_sum = _val; prio = rng(); } }; struct Treap{ Node *root; Treap(){ root = nullptr; } void Delete(Node *&root){ if (root == nullptr) return; Delete(root->left); Delete(root->right); delete root; root = nullptr; } void ClearAll(){ Delete(root); } ~Treap(){ ClearAll(); } long long GetGcd(Node *root){ if (root == nullptr) return 0; else return root->gcd_sum; } void Merge(Node *&root , Node *left , Node *right){ if (left == nullptr){ root = right; return; } if (right == nullptr){ root = left; return; } if (left->prio < right->prio){ Merge(left->right , left->right , right); root = left; } else{ Merge(right->left , left , right->left); root = right; } root->gcd_sum = __gcd(root->val , __gcd(GetGcd(root->left) , GetGcd(root->right))); } void Split(Node *root , Node *&left , Node *&right , int pos){ if (root == nullptr){ left = right = nullptr; return; } if (root->pos < pos){ Split(root->right , root->right , right , pos); left = root; } else{ Split(root->left , left , root->left , pos); right = root; } root->gcd_sum = __gcd(root->val , __gcd(GetGcd(root->left) , GetGcd(root->right))); } void Update(int pos , long long val){ Node *A , *B , *C , *D; A = B = C = D = nullptr; Split(root , A , B , pos); Split(B , C , D , pos + 1); delete C; C = new Node(pos , val); Merge(root , A , C); Merge(root , root , D); } long long GetRange(int l , int r){ Node *A , *B , *C , *D; A = B = C = D = nullptr; Split(root , A , B , l); Split(B , C , D , r + 1); long long ans = GetGcd(C); Merge(root , A , C); Merge(root , root , D); return ans; } }; struct Node2{ Treap T; Node2 *left , *right; Node2(){ T = Treap(); left = right = nullptr; }; }; struct SegmentTree{ Node2 *root; SegmentTree(){ root = new Node2(); } void Delete(Node2 *&root){ if (root == nullptr) return; Delete(root->left); Delete(root->right); (root->T).ClearAll(); } void ClearAll(){ Delete(root); } ~SegmentTree(){ ClearAll(); } void Update(Node2 *root , int l , int r , int x , int y , long long val){ if (l == r){ root->T.Update(y , val); return; } int mid = (l + r) / 2; if (x <= mid){ if (root->left == nullptr) root->left = new Node2(); Update(root->left , l , mid , x , y , val); } else{ if (root->right == nullptr) root->right = new Node2(); Update(root->right , mid + 1 , r , x , y , val); } long long left_gcd = (root->left == nullptr) ? 0 : (root->left->T).GetRange(y , y); long long right_gcd = (root->right == nullptr) ? 0 : (root->right->T).GetRange(y , y); long long combine_gcd = __gcd(left_gcd , right_gcd); root->T.Update(y , combine_gcd); } long long Get(Node2 *root , int l , int r , int x , int y , int u , int v){ if (u < l || r < x) return 0; if (x <= l && r <= u) return (root->T).GetRange(y , v); int mid = (l + r) / 2; long long left_gcd = (root->left == nullptr) ? 0 : Get(root->left , l , mid , x , y , u , v); long long right_gcd = (root->right == nullptr) ? 0 : Get(root->right , mid + 1 , r , x , y , u , v); return __gcd(left_gcd , right_gcd); } } S; void update(int x , int y , long long val){ S.Update(S.root , 0 , n - 1 , x , y , val); } long long calculate(int x , int y , int u , int v){ return S.Get(S.root , 0 , n - 1 , x , y , u , v); }
#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...