#include "wombats.h"
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define MASK(i) (1ULL << (i))
#define GETBIT(mask, i) (((mask) >> (i)) & 1)
#define ALL(v) (v).begin(), (v).end()
ll max(ll a, ll b){return (a > b) ? a : b;}
ll min(ll a, ll b){return (a < b) ? a : b;}
ll gcd(ll a, ll b){return __gcd(a, b);}
ll lcm(ll a, ll b){return a / gcd(a, b) * b;}
ll LASTBIT(ll mask){return (mask) & (-mask);}
int pop_cnt(ull mask){return __builtin_popcountll(mask);}
int ctz(ull mask){return __builtin_ctzll(mask);}
int logOf(ull mask){return 63 - __builtin_clzll(mask);}
mt19937_64 rng(chrono::high_resolution_clock::now().time_since_epoch().count());
ll rngesus(ll l, ll r){return l + (ull) rng() % (r - l + 1);}
double rngesus_d(double l, double r){
double wow = (double) ((ull) rng()) / ((ull)(0-1));
return wow * (r - l) + l;
}
template <class T1, class T2>
bool maximize(T1 &a, T2 b){
if (a < b) {a = b; return true;}
return false;
}
template <class T1, class T2>
bool minimize(T1 &a, T2 b){
if (a > b) {a = b; return true;}
return false;
}
template <class T>
void printArr(T container, string separator = " ", string finish = "\n", ostream &out = cout){
for(auto item: container) out << item << separator;
out << finish;
}
template <class T>
void remove_dup(vector<T> &a){
sort(ALL(a));
a.resize(unique(ALL(a)) - a.begin());
}
struct Slice{
vector<int> hori, verti;
};
const int R = 5000, C = 200, INF = 1e9 + 69;
struct Node{
int d[C][C];
Node(){
for(int i = 0; i < C; ++i)
for(int j = 0; j < C; ++j)
d[i][j] = INF;
}
};
const int BLOCK = 32;
int r, c;
int b_r;
vector<Slice> a;
Node produce_node(Slice x){
vector<int> pref = x.hori; pref.insert(pref.begin(), 0);
for(int i = 1; i < (int) pref.size(); ++i) pref[i] += pref[i-1];
Node ans;
for(int i = 0; i < c; ++i) for(int j = 0; j < c; ++j) {
ans.d[i][j] = abs(pref[j] - pref[i]) + x.verti[j];
}
return ans;
}
Node combine(Node x, Node y){
Node ans;
int opt[c][c];
memset(opt, 0, sizeof opt);
for(int i = c-1; i >= 0; --i) for(int j = 0; j < c; ++j){
int l = 0, r = c-1;
if (i < c-1) r = opt[i+1][j];
if (j > 0) l = opt[i][j-1];
for(int k = l; k <= r; ++k){
if (minimize(ans.d[i][j], x.d[i][k] + y.d[k][j]))
opt[i][j] = k;
}
}
return ans;
}
struct SegmentTree{
int n;
vector<Node> a;
SegmentTree(){}
SegmentTree(int _n, vector<Node> &b){
n = _n;
a.resize(n * 4 + 2);
build_tree(0, n-1, 1, b);
}
int choose_mid(int l,int r){
return (l + r) / 2;
int j = r - l + 1;
return min(l + MASK(j) - 1, r - MASK(j-1));
}
void build_tree(int l, int r, int id, vector<Node> &b){
if (l == r){
a[id] = b[l];
return;
}
int mid = choose_mid(l, r);
build_tree(l, mid, id * 2, b); build_tree(mid+1, r, id * 2 + 1, b);
a[id] = combine(a[id * 2], a[id * 2 + 1]);
}
void update(int i, Node v, int l, int r, int id){
if (l == r){
a[id] = v;
return;
}
int mid = choose_mid(l, r);
if (i <= mid) update(i, v, l, mid, id * 2);
else update(i, v, mid+1, r, id * 2 + 1);
a[id] = combine(a[id * 2], a[id * 2 + 1]);
}
void update(int i, Node v){
update(i, v, 0, n-1, 1);
}
Node get(){
return a[1];
}
};
SegmentTree st;
void init(int R, int C, int H[5000][200], int V[5000][200]) {
r = R, c = C;
for(int i = 0; i < r; ++i){
a.emplace_back();
a.back().hori.resize(c-1);
a.back().verti.resize(c);
for(int j = 0; j < c - 1; ++j)
a.back().hori[j] = H[i][j];
if (i < r - 1){
for(int j = 0; j < c; ++j)
a.back().verti[j] = V[i][j];
}
}
b_r = (r + BLOCK - 1) / BLOCK;
vector<Node> b;
for(int i = 0; i < b_r; ++i){
int L = i * BLOCK, R = min(r-1, (i+1) * BLOCK - 1);
Node cur = produce_node(a[L]);
for(int j = L+1; j <= R; ++j)
cur = combine(cur, produce_node(a[j]));
b.push_back(cur);
}
st = SegmentTree(b_r, b);
}
void changeH(int P, int Q, int W) {
a[P].hori[Q] = W;
int b_P = P / BLOCK;
int L = b_P * BLOCK, R = min(r-1, (b_P + 1) * BLOCK - 1);
Node b = produce_node(a[L]);
for(int j = L+1; j <= R; ++j) b = combine(b, produce_node(a[j]));
st.update(b_P, b);
}
void changeV(int P, int Q, int W) {
a[P].verti[Q] = W;
int b_P = P / BLOCK;
int L = b_P * BLOCK, R = min(r-1, (b_P + 1) * BLOCK - 1);
Node b = produce_node(a[L]);
for(int j = L+1; j <= R; ++j) b = combine(b, produce_node(a[j]));
st.update(b_P, b);
}
int escape(int V1, int V2) {
return st.get().d[V1][V2];
}
# | 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... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |