Submission #960646

# Submission time Handle Problem Language Result Execution time Memory
960646 2024-04-10T18:26:57 Z hazzle Land of the Rainbow Gold (APIO17_rainbow) C++17
12 / 100
1538 ms 473824 KB
#include "rainbow.h"

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>

//#pragma GCC optimize("Ofast,unroll-loops")
//#pragma GCC target("avx,avx2,fma")

using namespace std;
using namespace __gnu_pbds;

#define fi first
#define se second
#define all(m) (m).begin(), (m).end()
#define rall(m) (m).rbegin(), (m).rend()
#define vec vector
#define sz(a) (int) (a).size()
#define mpp make_pair
#define mtt make_tuple

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair <ll, ll> pll;
typedef pair <int, int> pii;
typedef tuple <int, int, int> tui;

template <typename T>
using prq = priority_queue <T>;

template <typename T>
using pgq = priority_queue <T, vec <T>, greater <T>>;

template <typename T> bool umin(T &a, T b) { return a > b ? a = b, 1 : 0; }
template <typename T> bool umax(T &a, T b) { return a < b ? a = b, 1 : 0; }

typedef struct node* pnode;
struct node{
     int s;
     pnode l, r;
     node(int x = 0): s(x) { l = r = nullptr; }
     node(pnode tl, pnode tr): l(tl), r(tr) {
          s = 0;
          if (l) s += l->s;
          if (r) s += r->s;
     }
};

pnode build(int tl, int tr){
     if (tl + 1 == tr) return new node();
     int tm = tl + tr >> 1;
     return new node(build(tl, tm), build(tm, tr));
}

pnode upd(int p, int x, int tl, int tr, pnode t){
     if (tl + 1 == tr) return new node(t->s + x);
     int tm = tl + tr >> 1;
     if (p < tm) return new node(upd(p, x, tl, tm, t->l), t->r);
     return new node(t->l, upd(p, x, tm, tr, t->r));
}

int get(int l, int r, int tl, int tr, pnode t){
     if (!t || l >= r) return 0;
     if (tl == l && tr == r) return t->s;
     int tm = tl + tr >> 1;
     return get(l, min(tm, r), tl, tm, t->l)
          + get(max(l, tm), r, tm, tr, t->r);
}

struct sum2d{
     int n, m;
     vec <pnode> t;
     vec <map <int, int>> updates;

     sum2d() {}

     sum2d(int n, int m): n(n), m(m) {
          t.resize(n);
          updates.resize(n);
     }

     void mark(int x, int y){
          assert(x < n);
          assert(x >= 0);
          assert(y < m);
          assert(y >= 0);
          updates[x][y] = 1;
     }

     void init(){
          t[0] = build(0, m);
          for (int i = 0; i < n; ++i){
               if (i) t[i] = t[i - 1];
               for (auto &[y, d]: updates[i]){
                    t[i] = upd(y, d, 0, m, t[i]);
               }
          }
     }

     int sum(int lx, int ly, int rx, int ry){ // sum on [lx, rx] U [ly, ry]
          int ans = get(ly, ry + 1, 0, m, t[rx]);
          if (lx) ans -= get(ly, ry + 1, 0, m, t[lx - 1]);
          return ans;
     }

     int at(int x, int y){
          int ans = get(y, y + 1, 0, m, t[x]);
          if (x) ans -= get(y, y + 1, 0, m, t[x - 1]);
          return ans;
     }
};

sum2d f, v_e, h_e, v;

void init(int R, int C, int sr, int sc, int M, char *S) {
     --sr, --sc;

     f = sum2d(R, C);
     v_e = sum2d(R, C + 1);
     h_e = sum2d(R + 1, C);
     v = sum2d(R + 1, C + 1);

     auto mark = [&](int x, int y){
          f.mark(x, y);
          v.mark(x, y);
          v.mark(x + 1, y);
          v.mark(x, y + 1);
          v.mark(x + 1, y + 1);
          h_e.mark(x, y);
          h_e.mark(x + 1, y);
          v_e.mark(x, y);
          v_e.mark(x, y + 1);
     };

     mark(sr, sc);
     for (int i = 0; i < M; ++i){
          if (S[i] == 'N') --sr;
          if (S[i] == 'S') ++sr;
          if (S[i] == 'W') --sc;
          if (S[i] == 'E') ++sc;
          mark(sr, sc);
     }
     f.init();
     v.init();
     h_e.init();
     v_e.init();
//     cout << "\n";
//     for (int i = 0; i < R; ++i){
//          for (int j = 0; j < C; ++j){
//               cout << f.at(i, j);
//          }
//          cout << "\n";
//     }
//     cout << "\n";
}

int colour(int lx, int ly, int rx, int ry) {
     --lx, --ly, --rx, --ry;

     int extra_faces = f.sum(lx, ly, rx, ry); // river cells

     int vertices = v.sum(lx, ly, rx + 1, ry + 1); // inside


     vertices += rx - lx + 2 - v.sum(lx, ly, rx + 1, ly);
     vertices += rx - lx + 2 - v.sum(lx, ry + 1, rx + 1, ry + 1);
     vertices += ry - ly - v.sum(lx, ly + 1, lx, ry);
     vertices += ry - ly - v.sum(rx + 1, ly + 1, rx + 1, ry); // borders

//     cout << "inside: " << v.sum(lx, ly, rx + 1, ry + 1) << "\n";
//     cout << "left border: " << rx - lx + 2 << " - " << v.sum(lx, ly, rx + 1, ly) << "\n";
//     cout << "right border: " << rx - lx + 2 << " - " << v.sum(lx, ry + 1, rx + 1, ry + 1) << "\n";
//     cout << "top border: " << ry - ly << " - " << v.sum(lx, ly + 1, lx, ry) << "\n";
//     cout << "bottom border: " << ry - ly << " - " << v.sum(rx + 1, ly + 1, rx + 1, ry) << "\n";
//     cout << "\n";

     int v_edges = v_e.sum(lx, ly, rx, ry + 1); // inside
     v_edges += rx - lx + 1 - v_e.sum(lx, ly, rx, ly);
     v_edges += rx - lx + 1 - v_e.sum(lx, ry + 1, rx, ry + 1); // borders

     int h_edges = h_e.sum(lx, ly, rx + 1, ry); //inside
     h_edges += ry - ly + 1 - h_e.sum(lx, ly, lx, ry);
     h_edges += ry - ly + 1 - h_e.sum(rx + 1, ly, rx + 1, ry); // borders

//     cout << "hor inside: " << h_e.sum(lx, ly, rx + 1, ry) << "\n";
//     cout << "hor top border: " << ry - ly + 1 << " - " << h_e.sum(lx, ly, lx, ry) << "\n";
//     cout << "hor bottom border: " << ry - ly + 1 << " - " << h_e.sum(rx + 1, ly, rx + 1, ry) << "\n";
//     cout << "\n";
//
//     cout << "v_e:" << v_edges << "\n";
//     cout << "h_e:" << h_edges << "\n";
//     cout << "v:" << vertices << "\n";
//     cout << "e_f:" << extra_faces << "\n";

     return 2 + v_edges + h_edges - vertices - extra_faces - 1; //using v - e + f = 2 => f = 2 + e - v
}

Compilation message

rainbow.cpp: In function 'node* build(int, int)':
rainbow.cpp:51:18: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   51 |      int tm = tl + tr >> 1;
      |               ~~~^~~~
rainbow.cpp: In function 'node* upd(int, int, int, int, pnode)':
rainbow.cpp:57:18: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   57 |      int tm = tl + tr >> 1;
      |               ~~~^~~~
rainbow.cpp: In function 'int get(int, int, int, int, pnode)':
rainbow.cpp:65:18: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   65 |      int tm = tl + tr >> 1;
      |               ~~~^~~~
# Verdict Execution time Memory Grader output
1 Correct 2 ms 600 KB Output is correct
2 Correct 4 ms 1628 KB Output is correct
3 Incorrect 3 ms 604 KB Output isn't correct
4 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 0 ms 344 KB Output is correct
2 Correct 0 ms 348 KB Output is correct
3 Correct 1165 ms 280288 KB Output is correct
4 Correct 1538 ms 433432 KB Output is correct
5 Correct 1512 ms 430344 KB Output is correct
6 Correct 1317 ms 343860 KB Output is correct
7 Correct 1258 ms 338552 KB Output is correct
8 Correct 647 ms 54140 KB Output is correct
9 Correct 1481 ms 433116 KB Output is correct
10 Correct 1512 ms 430068 KB Output is correct
11 Correct 1301 ms 344012 KB Output is correct
12 Correct 638 ms 406544 KB Output is correct
13 Correct 702 ms 433096 KB Output is correct
14 Correct 747 ms 430056 KB Output is correct
15 Correct 609 ms 343792 KB Output is correct
16 Correct 1201 ms 321740 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 1 ms 440 KB Output is correct
2 Correct 629 ms 473824 KB Output is correct
3 Correct 402 ms 473304 KB Output is correct
4 Correct 438 ms 473624 KB Output is correct
5 Correct 373 ms 378584 KB Output is correct
6 Correct 157 ms 165432 KB Output is correct
7 Incorrect 289 ms 236348 KB Output isn't correct
8 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 2 ms 600 KB Output is correct
2 Correct 4 ms 1628 KB Output is correct
3 Incorrect 3 ms 604 KB Output isn't correct
4 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 2 ms 600 KB Output is correct
2 Correct 4 ms 1628 KB Output is correct
3 Incorrect 3 ms 604 KB Output isn't correct
4 Halted 0 ms 0 KB -