image.png

image.png

image.png

문제 태그

아이디어

  1. 맨해튼의 거리에 절대값을 풀어 다음 4가지 형태 중 하나의 최대값으로 바꿀 수 있다

    $$ \lvert x_1-x_2\rvert+\lvert y_1-y_2\rvert =\max\left\{ \begin{aligned} &(x_1+y_1)-(x_2+y_2)\\ &(x_1-y_1)-(x_2-y_2)\\ &(-x_1+y_1)-(-x_2+y_2)\\ &(-x_1-y_1)-(-x_2-y_2) \end{aligned} \right\} $$

    즉 쿼리는 이 4개의 값 중 최대를 뽑는 문제

  2. 구간 쿼리 + 갱신 + 최댓값 문제

  3. 자료구조 설계

  4. 세그먼트 트리 구조

  5. 쿼리 처리 방식

  6. 핵심 아이디어 요약

  7. 직관적 이해

정답

#include <bits/stdc++.h>
#include <atcoder/segtree>

using namespace std;
using namespace atcoder;

using ll = long long;
using pii = pair<int, int>;
using vi = vector<int>;
using vll = vector<ll>;

#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define F first
#define S second
#define pb push_back
#define mp make_pair
#define lb lower_bound
#define ub upper_bound

#ifndef ONLINE_JUDGE
template<typename A, typename B>
ostream& operator<<(ostream& os, const pair<A, B>& p) {
    return os << "{" << p.first << ", " << p.second << "}";
}
template<typename T>
ostream& operator<<(ostream& os, const vector<T>& v) {
    os << "[";
    for (size_t i = 0; i < v.size(); ++i) {
        os << v[i];
        if (i != v.size() - 1) os << ", ";
    }
    return os << "]";
}
#define debug(...) cerr << "[DEBUG] " << #__VA_ARGS__ << ": ", DBG(__VA_ARGS__)
template<typename T> void DBG(const T& v) { cerr << v << endl; }
template<typename T, typename... Args> void DBG(const T& v, const Args&... args) { cerr << v << ", "; DBG(args...); }
#else
#define debug(...)
#endif

const ll INF = 4e18; 

struct Data {
    ll v[4];
};

Data op(Data a, Data b) {
    Data res;
    for(int i = 0; i < 4; i++) {
        res.v[i] = max(a.v[i], b.v[i]);
    }
    return res;
}

Data e() {
    Data res;
    for(int i = 0; i < 4; i++) res.v[i] = -INF;
    return res;
}

Data make_data(ll x, ll y) {
    Data res;
    res.v[0] = x + y;
    res.v[1] = x - y;
    res.v[2] = -x + y;
    res.v[3] = -x - y;
    return res;
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    
    int N, Q;
    cin >> N >> Q;

    vector<Data> initial_data(N);
    for(int i = 0; i < N; i++) {
        ll x, y;
        cin >> x >> y;
        initial_data[i] = make_data(x, y);
    }

    segtree<Data, op, e> seg(initial_data);

    while(Q--) {
        int type;
        cin >> type;
        if (type == 1) {
            int i;
            ll x, y;
            cin >> i >> x >> y;
            seg.set(i - 1, make_data(x, y));
        } else {
            int L, R;
            ll x, y;
            cin >> L >> R >> x >> y;

            Data res = seg.prod(L - 1, R);

            ll ans = -INF;
            ans = max(ans, res.v[0] - (x + y));
            ans = max(ans, res.v[1] - (x - y));
            ans = max(ans, res.v[2] - (-x + y));
            ans = max(ans, res.v[3] - (-x - y));
            
            cout << ans << "\\n";
        }
    }
    
    return 0;
}