CodeForces 1924B Space Harbour
不知道为什么好像大家在这题上花了挺久的。
发现对于一对相邻的港口 , 的花费是 。拆开得 。
考虑用 set 维护所有港口,这样可以知道一个港口左边和右边的港口的坐标和价值。那么前一项 可以线段树区间覆盖,后一项 也可以线段树区间覆盖处理,相当于让一个代表 区间的线段树结点的和变成 。这个标记是可以下传的。
总时间复杂度为 。
code
// Problem: B. Space Harbour // Contest: Codeforces - Codeforces Round 921 (Div. 1) // URL: https://codeforces.com/contest/1924/problem/B // Memory Limit: 256 MB // Time Limit: 2000 ms // // Powered by CP Editor (https://cpeditor.org) #include <bits/stdc++.h> #define pb emplace_back #define fst first #define scd second #define mkp make_pair #define mems(a, x) memset((a), (x), sizeof(a)) using namespace std; typedef long long ll; typedef double db; typedef unsigned long long ull; typedef long double ldb; typedef pair<ll, ll> pii; const int maxn = 300100; ll n, m, q, a[maxn], b[maxn]; inline ll calc(ll l, ll r) { return (l + r) * (r - l + 1) / 2; } struct { ll a[maxn << 2], tag[maxn << 2]; inline void pushup(int x) { a[x] = a[x << 1] + a[x << 1 | 1]; } inline void init() { mems(tag, -1); } inline void pushdown(int x, int l, int r) { if (tag[x] == -1) { return; } int mid = (l + r) >> 1; a[x << 1] = tag[x] * (mid - l + 1); a[x << 1 | 1] = tag[x] * (r - mid); tag[x << 1] = tag[x << 1 | 1] = tag[x]; tag[x] = -1; } void update(int rt, int l, int r, int ql, int qr, ll x) { if (ql > qr) { return; } if (ql <= l && r <= qr) { a[rt] = x * (r - l + 1); tag[rt] = x; return; } pushdown(rt, l, r); int mid = (l + r) >> 1; if (ql <= mid) { update(rt << 1, l, mid, ql, qr, x); } if (qr > mid) { update(rt << 1 | 1, mid + 1, r, ql, qr, x); } pushup(rt); } ll query(int rt, int l, int r, int ql, int qr) { if (ql <= l && r <= qr) { return a[rt]; } pushdown(rt, l, r); int mid = (l + r) >> 1; ll res = 0; if (ql <= mid) { res += query(rt << 1, l, mid, ql, qr); } if (qr > mid) { res += query(rt << 1 | 1, mid + 1, r, ql, qr); } return res; } } t1; struct { ll a[maxn << 2], tag[maxn << 2]; inline void pushup(int x) { a[x] = a[x << 1] + a[x << 1 | 1]; } inline void init() { mems(tag, -1); } inline void pushdown(int x, int l, int r) { if (tag[x] == -1) { return; } int mid = (l + r) >> 1; a[x << 1] = tag[x] * calc(l, mid); a[x << 1 | 1] = tag[x] * calc(mid + 1, r); tag[x << 1] = tag[x << 1 | 1] = tag[x]; tag[x] = -1; } void update(int rt, int l, int r, int ql, int qr, ll x) { if (ql > qr) { return; } if (ql <= l && r <= qr) { a[rt] = x * calc(l, r); tag[rt] = x; return; } pushdown(rt, l, r); int mid = (l + r) >> 1; if (ql <= mid) { update(rt << 1, l, mid, ql, qr, x); } if (qr > mid) { update(rt << 1 | 1, mid + 1, r, ql, qr, x); } pushup(rt); } ll query(int rt, int l, int r, int ql, int qr) { if (ql <= l && r <= qr) { return a[rt]; } pushdown(rt, l, r); int mid = (l + r) >> 1; ll res = 0; if (ql <= mid) { res += query(rt << 1, l, mid, ql, qr); } if (qr > mid) { res += query(rt << 1 | 1, mid + 1, r, ql, qr); } return res; } } t2; set<pii> S; inline void upd(ll x, ll y, ll z) { t1.update(1, 1, n, x + 1, y - 1, z * y); t2.update(1, 1, n, x + 1, y - 1, -z); } void solve() { t1.init(); t2.init(); scanf("%lld%lld%lld", &n, &m, &q); for (int i = 1; i <= m; ++i) { scanf("%lld", &a[i]); } for (int i = 1; i <= m; ++i) { scanf("%lld", &b[i]); S.emplace(a[i], b[i]); } for (auto it = S.begin(); next(it) != S.end(); ++it) { auto jt = next(it); upd(it->fst, jt->fst, it->scd); } while (q--) { ll op, x, y; scanf("%lld%lld%lld", &op, &x, &y); if (op == 1) { S.emplace(x, y); t1.update(1, 1, n, x, x, 0); t2.update(1, 1, n, x, x, 0); auto it = S.find(mkp(x, y)); auto p = prev(it), q = next(it); upd(p->fst, it->fst, p->scd); upd(it->fst, q->fst, it->scd); } else { printf("%lld\n", t1.query(1, 1, n, x, y) + t2.query(1, 1, n, x, y)); } } } int main() { int T = 1; // scanf("%d", &T); while (T--) { solve(); } return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】