P5251 [LnOI2019] 第二代图灵机

cxqghzj·2023-12-25 09:13·6 次阅读

P5251 [LnOI2019] 第二代图灵机

题意#

给定一个数列。每个数字有一个颜色。

单点修改数字,区间修改颜色。

求:

  • 包含所有颜色的数字和最小的区间
  • 没有重复颜色的数字和最大的区间

数据随机。

Sol#

数据随机,直接上珂朵莉树。

跑双指针的时候套个线段树求最大最小区间和就行。

Code#

Copy
#include <iostream> #include <algorithm> #include <cstdio> #include <array> #include <set> #include <queue> #include <cassert> #define int long long using namespace std; #ifdef ONLINE_JUDGE #define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++) char buf[1 << 23], *p1 = buf, *p2 = buf, ubuf[1 << 23], *u = ubuf; #endif int read() { int p = 0, flg = 1; char c = getchar(); while (c < '0' || c > '9') { if (c == '-') flg = -1; c = getchar(); } while (c >= '0' && c <= '9') { p = p * 10 + c - '0'; c = getchar(); } return p * flg; } void write(int x) { if (x < 0) { x = -x; putchar('-'); } if (x > 9) { write(x / 10); } putchar(x % 10 + '0'); } #define fi first #define se second const int N = 1e5 + 5, inf = 1e18; array <int, N> s; namespace Sgt { array <int, N * 4> kmax, kmin, edge; void pushup(int x) { edge[x] = edge[x * 2] + edge[x * 2 + 1]; kmax[x] = max(kmax[x * 2], kmax[x * 2 + 1]); kmin[x] = min(kmin[x * 2], kmin[x * 2 + 1]); } void build(int x, int l, int r) { if (l == r) { edge[x] = kmax[x] = kmin[x] = s[l]; return; } int mid = (l + r) >> 1; build(x * 2, l, mid); build(x * 2 + 1, mid + 1, r); pushup(x); } void modify(int x, int l, int r, int k, int y) { if (k > r || k < l) return; if (l == r) { edge[x] = kmin[x] = kmax[x] = y; return; } int mid = (l + r) >> 1; if (k <= mid) modify(x * 2, l, mid, k, y); else modify(x * 2 + 1, mid + 1, r, k, y); pushup(x); } int query(int x, int l, int r, int L, int R) { if (L > r || R < l) return 0; if (L <= l && R >= r) return edge[x]; int mid = (l + r) >> 1, ans = 0; if (L <= mid) ans += query(x * 2, l, mid, L, R); if (R > mid) ans += query(x * 2 + 1, mid + 1, r, L, R); return ans; } int query_max(int x, int l, int r, int L, int R) { if (L > r || R < l) return 0; if (L <= l && R >= r) return kmax[x]; int mid = (l + r) >> 1, ans = 0; if (L <= mid) ans = max(ans, query_max(x * 2, l, mid, L, R)); if (R > mid) ans = max(ans, query_max(x * 2 + 1, mid + 1, r, L, R)); return ans; } int query_min(int x, int l, int r, int L, int R) { if (L > r || R < l) return inf; if (L <= l && R >= r) return kmin[x]; int mid = (l + r) >> 1, ans = inf; if (L <= mid) ans = min(ans, query_min(x * 2, l, mid, L, R)); if (R > mid) ans = min(ans, query_min(x * 2 + 1, mid + 1, r, L, R)); return ans; } } namespace Chtholly { class Node { public: int l, r; mutable int v; Node (int _l, int _r, int _v): l(_l), r(_r), v(_v) {} bool operator <(const Node &t) const { return l < t.l; } }; set <Node> Cht; auto split(int x, int n) { if (x > n) return Cht.end(); auto it = --Cht.upper_bound(Node(x, 0, 0)); if (it -> l == x) return it; int l = it -> l, r = it -> r, v = it -> v; Cht.erase(it); Cht.insert(Node(l, x - 1, v)); return Cht.insert(Node(x, r, v)).fi; } void assign(int l, int r, int v, int n) { auto itr = split(r + 1, n), itl = split(l, n); Cht.erase(itl, itr); Cht.insert(Node(l, r, v)); } array <int, 105> cur; int tot = 0; void add(int x) { cur[x]++; if (cur[x] == 1) tot++; } void del(int x) { cur[x]--; if (!cur[x]) tot--; } int query1(int _l, int _r, int n, int m) { auto itr = split(_r + 1, n), itl = split(_l, n), l = itl; int ans = inf; if (m == 1) return Sgt::query_min(1, 1, n, _l, _r); tot = 0; cur.fill(0); for (auto r = itl; r != itr; r++) { add(r -> v); while (cur[l -> v] > 1) del(l -> v), l++; if (tot == m) ans = min(ans, Sgt::query(1, 1, n, l -> r, r -> l)); } return ans == inf ? -1 : ans; } int query2(int _l, int _r, int n, int m) { auto itr = split(_r + 1, n), itl = split(_l, n); int ans = Sgt::query_max(1, 1, n, _l, _r); cur.fill(0); auto r = itl; cur[itl -> v] = 1; for (auto l = itl; l != itr; cur[l -> v]--, l++) { while ((!(r -> r - r -> l) || l == r) && !cur[next(r, 1) -> v] && next(r, 1) != itr) r++, cur[r -> v]++; if (l != r) ans = max(ans, Sgt::query(1, 1, n, l -> r, r -> l)); if (l == r) r++, cur[r -> v]++; } assert(ans > 0); return ans; } } signed main() { int n = read(), q = read(), m = read(); for (int i = 1; i <= n; i++) s[i] = read(); Sgt::build(1, 1, n); for (int i = 1; i <= n; i++) Chtholly::Cht.insert(Chtholly::Node(i, i, read())); while (q--) { int op = read(); /* assert(op != 4); */ if (op == 1) { int x = read(), y = read(); Sgt::modify(1, 1, n, x, y); s[x] = y; } if (op == 2) { int l = read(), r = read(), y = read(); Chtholly::assign(l, r, y, n); } if (op == 3) { int l = read(), r = read(); write(Chtholly::query1(l, r, n, m)), puts(""); } if (op == 4) { int l = read(), r = read(); write(Chtholly::query2(l, r, n, m)), puts(""); } } return 0; }
posted @   cxqghzj  阅读(6)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
点击右上角即可分享
微信分享提示
目录