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;
}

浙公网安备 33010602011771号