NC20593. [SHOI2015]脑洞治疗仪
描述
输入描述
第一行两个整数n,m。表示SHTSC的大脑可分为从1到n编号的n个连续区域。有m个操作。以下m行每行是下列三种格式之一。0 l r :SHTSC挖了一个从l到r的脑洞。1 l0 r0 l1 r2 :SHTSC进行了一次脑洞治疗,用从l0到r0的脑组织修补l1到r1的脑洞。2 l r :SHTSC询问l到r这段区间最大的脑洞有多大。n,m ≤ 200000,1 ≤ l ≤ r ≤ n
输出描述
对于每个询问,输出一行一个整数,表示询问区间内最大连续脑洞区域有多大。
示例1
输入:
10 10 0 2 2 0 4 6 0 10 10 2 1 10 1 8 10 1 4 2 1 10 1 1 4 8 10 2 1 10 1 7 10 1 6 2 1 10
输出:
3 3 6 6
C++11(clang++ 3.9) 解法, 执行用时: 282ms, 内存消耗: 844K, 提交时间: 2020-07-01 18:11:47
#include <bits/stdc++.h> using namespace std; typedef long long ll; inline int read() { char c = getchar(); int x = 0, f = 1; while (c < '0' || c > '9') { if (c == '-') f = -1; c = getchar(); } while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar(); return x * f; } struct Node_t { int l, r; mutable int v; bool operator < (const Node_t &o) const { return l < o.l; } }; set<Node_t> odt; int n, m, pl, pr; inline set<Node_t>::iterator Split(int x) { if (x > n) return odt.end(); auto it = --odt.upper_bound({ x, 0, 0 }); if (it->l == x) return it; int l = it->l, r = it->r, v = it->v; odt.erase(it); odt.insert({ l, x - 1, v }); return odt.insert({ x, r, v }).first; } inline void Assign(int l, int r, int v) { auto itr = Split(r + 1), itl = Split(l); odt.erase(itl, itr); odt.insert({ l, r, v }); } inline int Count(int l, int r) { auto itr = Split(r + 1), itl = Split(l); int ret = 0; for (; itl != itr; itl++) if (itl->v == 1) ret += itl->r - itl->l + 1; return ret; } inline void Modify(int l, int r, int p) { auto itr = Split(r + 1), itl = Split(l); int ret = 0; if (!p) return; for (; itl != itr; itl++) if (!(itl->v)) { int now = itl->r - itl->l + 1; if (now <= p) { p -= now; itl->v = 1; } else { pl = itl->l; pr = pl + p - 1; p = 0; } if (!p) return; } } inline int Query(int l, int r) { auto itr = Split(r + 1), itl = Split(l); int Mx = 0, lst = 0; for (; itl != itr; itl++) if (!(itl->v)) { lst += itl->r - itl->l + 1; Mx = max(Mx, lst); } else lst = 0; return Mx; } int main() { n = read(); m = read(); odt.insert({ 1, n, 1 }); while (m--) { int opt = read(), l = read(), r = read(); if (!opt) Assign(l, r, 0); else if (opt == 1) { int x = read(), y = read(), p = Count(l, r); pl = pr = -1; Assign(l, r, 0); Modify(x, y, p); if (pl != -1 && pr != -1) Assign(pl, pr, 1); } else printf("%d\n", Query(l, r)); } return 0; }