Submission #332942

#TimeUsernameProblemLanguageResultExecution timeMemory
332942gmyuGame (IOI13_game)C++14
100 / 100
7891 ms57032 KiB
/* ID: USACO_template LANG: C++ PROG: USACO */ #include <iostream> //cin , cout #include <fstream> //fin, fout #include <stdio.h> // scanf , pringf #include <cstdio> #include <algorithm> // sort , stuff #include <stack> // stacks #include <queue> // queues #include <map> #include <string> #include "game.h" using namespace std; typedef pair<int, int> pii; typedef vector<int> vi; /// adjlist without weight typedef vector<pii> vii; /// adjlist with weight typedef vector<pair<int,pii>> vpip; /// edge with weight typedef long long ll; #define mp make_pair #define fst first #define snd second #define pb push_back #define trav(u, adj_v) for (auto& u: adj_v) const int MOD = 1e9+7; // 998244353; const int MX = 2e5+5; // const ll INF = 1e18; // #define MAXV 100007 #define MAXE 100007 /// code from USACO examples void setIO(string name) { ios_base::sync_with_stdio(0); cin.tie(0); freopen((name+".in").c_str(),"r",stdin); freopen((name+".out").c_str(),"w",stdout); } bool debug = false, submit = true; long long gcd2(long long X, long long Y) { if(X == 0) return Y; if(Y == 0) return X; long long tmp; while (X != Y && Y != 0) { tmp = X; X = Y; Y = tmp % Y; } return X; } /* Naively, inserting N elements into a sparse segment tree requires O(N log C) memory, giving a bound of O(N log^2C) on 2D segment tree memory. This is usually too much for N=C=10^5 and 256 MB Possible ways to get around this: - Use arrays of fixed size rather than pointers. - Reduce the memory usage of sparse segment tree to $O(N)$ while maintaining the same O(N\log C) insertion time (see the solution for IOI Game below for details). - Use BBSTs instead of sparse segment trees: https://cp-algorithms.com/data_structures/treap.html */ /// 2D segment tree with Treap on Y to reduce memory struct NODEY { int key, priority; long long val, ans; NODEY *l, *r; NODEY(int _key, long long _val) : key(_key), priority(rand() + (rand() << 15)), val(_val), ans(_val), l(NULL), r(NULL) {} }; typedef NODEY* pNODEY; int NYseg[2]; long long ans(pNODEY t) { return t ? t->ans : 0; } void pullY(pNODEY t) { if (t) t->ans = gcd2(gcd2(ans(t->l), ans(t->r)), t->val); } void splitY(pNODEY t, int key, pNODEY &l, pNODEY &r) { if (!t) l = r = NULL; else if (key < t->key) splitY(t->l, key, l, t->l), r = t; else splitY(t->r, key, t->r, r), l = t; pullY(t); } void mergeY(pNODEY &t, pNODEY l, pNODEY r) { if (!l || !r) t = l ? l : r; else if (l->priority > r->priority) mergeY(l->r, l->r, r), t = l; else mergeY(r->l, l, r->l), t = r; pullY(t); } long long queY(int l, int r, pNODEY t) { // [l, r] pNODEY pl, pm, pr; splitY(t, l-1, pl, pm); splitY(pm, r, t, pr); long long ret = ans(t); mergeY(pm, pl, t); mergeY(t, pm, pr); return ret; } void updY(int p, long long val, pNODEY &t) { pNODEY pl, pm, pr; splitY(t, p-1, pl, pm); splitY(pm, p, t, pr); if (t) t->val = t->ans = val; else t = new NODEY(p, val); mergeY(pm, pl, t); mergeY(t, pm, pr); } struct NODEX { NODEX *lp, *rp; // left ptr, right ptr pNODEY pny; NODEX() : lp(NULL), rp(NULL), pny(NULL) {} }; NODEX nx; int NXseg[2]; void pullX(int vty, NODEX *pnx) { ll g1 = (!pnx->lp) ? 0LL : queY(vty, vty, pnx->lp->pny); ll g2 = (!pnx->rp) ? 0LL : queY(vty, vty, pnx->rp->pny); ll g0 = gcd2(g1, g2); updY(vty, g0, pnx->pny); } void updX(int vtx, int vty, ll val, NODEX *pnx, int l = NXseg[0], int r = NXseg[1]){ if(l == r) { updY(vty, val, pnx->pny); return; } // leaf int mid = (l + r) / 2; if (vtx <= mid) { if(!pnx->lp) pnx->lp = new NODEX(); updX(vtx, vty, val, pnx->lp, l, mid); } else { if(!pnx->rp) pnx->rp = new NODEX(); updX(vtx, vty, val, pnx->rp, mid+1, r); } pullX(vty, pnx); } ll queX(int qxle, int qxri, int qyle, int qyri, NODEX *pnx, int l = NXseg[0], int r = NXseg[1]) { // [l, r] if(r < qxle || l > qxri) return 0LL; if(qxle <= l && r <= qxri) return queY(qyle, qyri, pnx->pny); int mid = (l + r) / 2; ll g1 = (!pnx->lp) ? 0LL : queX(qxle, qxri, qyle, qyri, pnx->lp, l, mid); ll g2 = (!pnx->rp) ? 0LL : queX(qxle, qxri, qyle, qyri, pnx->rp, mid+1, r); return gcd2(g1, g2); } void init(int R, int C) { NXseg[0] = 0; NXseg[1] = C - 1; NYseg[0] = 0; NYseg[1] = R - 1; } void update(int P, int Q, long long K) { updX(Q, P, K, &nx); } long long calculate(int y10, int x10, int y20, int x20) { int x1 = min(x10, x20), x2 = max(x10, x20); int y1 = min(y10, y20), y2 = max(y10, y20); return queX(x1, x2, y1, y2, &nx); }

Compilation message (stderr)

game.cpp: In function 'void setIO(std::string)':
game.cpp:42:12: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)', declared with attribute warn_unused_result [-Wunused-result]
   42 |     freopen((name+".in").c_str(),"r",stdin);
      |     ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
game.cpp:43:12: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)', declared with attribute warn_unused_result [-Wunused-result]
   43 |     freopen((name+".out").c_str(),"w",stdout);
      |     ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#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...