rprmq1 题解

题解? 吐槽。

题目传送门

这题数据把我的快写卡了,我本地拍了 $10^5$ 组数据,$n \ge 500$ 死活过不了,然后突发奇想换了快写,然后就过了。还有 $n$ 要开大一点,大概 $1e5 \sim 5e5$ 左右,不知道为什么,反正不开大一点我最后一组数据过不去。

本题只要想到猫树分治后就很好做了,不多提。

#include<bits/stdc++.h>
using namespace std;

#define endl '\n'
#define gc getchar
#define R(i ,a, b) for(int i = a;i <= b; ++i)
#define F(i, a, b) for(int i = a;i >= b; --i)

typedef long long ll;
const int N = 1e6 + 500;
const int M = 1e6 + 500;

template<class T> 
void read(T &x) {
    T f = 1; x = 0;
    char c = gc();
    while(!isdigit(c)) c == '-' ? f = -1 : false, c = gc(); 
    while(isdigit(c)) x = (x << 3) + (x << 1) + (c ^ 48), c = gc();
    x *= f;
}
template<typename T, typename ... Args>
void read(T &t, Args &...args) {
    read(t), read(args...);
}
template<class T> 
void write(T x) {
    if(x < 0) putchar('-'), x = -x;
    if(x > 9) write(x / 10);
    putchar(x % 10 + '0');
}
template<class T> 
void write(T x, char s) {
    write(x), putchar(s);
}

int n, m, q;
struct Segment_Tree{
    #define lc k << 1
    #define rc k << 1 | 1
    #define lcon lc, l, mid
    #define rcon rc, mid + 1, r
    #define Mid int mid = l + r >> 1

    ll tmax[N << 2], add[N << 2], hmax[N << 2], hadd[N << 2], Res[N << 2];

    void pu_up(int k) {
        tmax[k] = max(tmax[lc], tmax[rc]);
        hmax[k] = max(hmax[lc], hmax[rc]);
    }

    void Add(int k, ll v, ll hv) {
        hadd[k] = max(hadd[k], add[k] + hv);
        add[k] += v, tmax[k] += v;
        hmax[k] = max(hmax[k], tmax[k] - add[k] + hadd[k]);
    }

    void Re_set(int k) {
        Add(lc, add[k], hadd[k]), Add(rc, add[k], hadd[k]);
        add[k] = hadd[k] = 0, hmax[k] = tmax[k], Res[k] = 1;
    }

    void pu_do(int k) {
        if(Res[k]) Re_set(lc), Re_set(rc), Res[k] = 0; 
        if(!add[k] && !hadd[k]) return ; Add(lc, add[k], hadd[k]);
        Add(rc, add[k], hadd[k]), add[k] = hadd[k] = 0;
    }

    void modify(int k, int l, int r, int x, int y, ll v) {
        if(x <= l && r <= y) return Add(k, v, max(0ll, v)); 
        Mid; pu_do(k); if(x <= mid) modify(lcon, x, y, v);
        if(y > mid) modify(rcon, x, y, v); pu_up(k);
    }

    ll query(int k, int l, int r, int x, int y) {
        if(x <= l && r <= y) return hmax[k];
        Mid; pu_do(k); ll ans = 0; if(x <= mid) ans = query(lcon, x, y);
        if(y > mid) ans = max(ans, query(rcon, x, y)); return ans;
    }

    void modify(int x, int y, ll v) { modify(1, 1, n, x, y, v); } 
    ll query(int x, int y) {return query(1, 1, n, x, y);} 
} ti;

struct QUIZ{
    int x1, y1, x2, y2;
    ll ans;
} iq[M]; // inquire

struct node { int x; ll vl; };
bool cmp(node a, node b) {return a.vl < b.vl; } 

int x_1, y_1, x_2, y_2; 
int t[M], lq[M], rq[M];
ll Re_vl;
vector<node> At[N]; 

void Update(int i, int ot) {
    if(ot == 1) for(auto [P, Q] : At[i]) ti.modify(P, n, Q);
    else for(auto it = At[i].rbegin(); it != At[i].rend(); it++) ti.modify(it->x, n, -it->vl);
}

void Print() {for(int i = 1; i <= n; ++i) cerr << ti.query(i, i) << " "; cerr << endl;} // 调试 

void solve(int l, int r, int ql, int qr) {
    if(ql > qr || l > r) return ;

    int mid = l + r >> 1, lcnt = 0, rcnt = 0, qnt = 0; 
    vector<int> nq; auto it = nq.begin();

    R(i ,ql, qr) {
        if(iq[t[i]].x2 < mid) lq[++lcnt] = t[i];
        else if(iq[t[i]].x1 > mid + 1) rq[++rcnt] = t[i];
        else nq.push_back(t[i]);
    }
    qnt = ql - 1;
    R(i, 1, lcnt) t[++qnt] = lq[i];  R(i, 1, rcnt) t[++qnt] = rq[i]; 

    if(!nq.size()) {
        R(i ,l, mid) Update(i , 1);
        if(l != r) solve(mid + 1, r, ql + lcnt, ql + lcnt + rcnt - 1); 
        F(i, mid, l) Update(i , -1);
        if(l != r) solve(l, mid, ql, ql + lcnt - 1);
        return ;
    }

    sort(nq.begin(), nq.end(), [](int a, int b){ return iq[a].x2 < iq[b].x2;}), it = nq.begin();

    R(i ,l, mid) Update(i , 1); // Statistics Left Interval Contribution   

    while(it != nq.end() && iq[*it].x2 <= mid) it++; 
    R(i, mid + 1, r) {
        Update(i, 1); 
        if(i == mid + 1) ti.Re_set(1); 
        while(it != nq.end() && iq[*it].x2 == i) { 
            iq[*it].ans = max(iq[*it].ans, ti.query(iq[*it].y1, iq[*it].y2));
            it++;
        }

    }   

    F(i, r, mid + 1) Update(i, -1);  // Delete Right Interval Contribution

    if(l != r) solve(mid + 1, r, ql + lcnt, ql + lcnt + rcnt - 1); 
    sort(nq.begin(), nq.end(), [](int a, int b){ return iq[a].x1 > iq[b].x1;}), it = nq.begin();

    while(it != nq.end() && iq[*it].x1 >= mid + 1) it++; 
    F(i, mid, l) {
        if(i == mid) ti.Re_set(1);
        while(it != nq.end() &&  iq[*it].x1 == i) {
            iq[*it].ans = max(iq[*it].ans, ti.query(iq[*it].y1, iq[*it].y2));
            it++;
        }
        Update(i, -1);
    }

    if(l != r) solve(l, mid, ql, ql + lcnt - 1);
}

void Init();

signed main() {
    Init();
    solve(1, n, 1, q);
    R(i ,1, q) write(iq[i].ans, '\n');
    return 0;
}

void Init() {
    read(n, m, q); 

    R(i, 1, m) {
        read(x_1, y_1, x_2, y_2, Re_vl);
        At[x_1].push_back(node{y_1, Re_vl}), At[x_2 + 1].push_back(node{y_2 + 1, Re_vl});
        At[x_2 + 1].push_back(node{y_1, -Re_vl}), At[x_1].push_back(node{y_2 + 1, -Re_vl});
    }
    for(int i = 1; i <= n; ++i) sort(At[i].begin(), At[i].end(), cmp);

    R(i ,1, q) { QUIZ &S = iq[i]; read(S.x1, S.y1, S.x2, S.y2); }
    R(i, 1, q) t[i] = i;

}
posted @ 2023-10-27 20:00  Saka_Noa  阅读(20)  评论(0)    收藏  举报  来源