P4690 镜中的昆虫 (动态区间颜色数) 题解

news/2024/10/7 9:07:27/文章来源:https://www.cnblogs.com/laijinyi/p/18449756

Statement

  • 区间涂颜色
  • 区间颜色数

Solution

\(O(\text{polysqrt})\)

略。

\(O(\text{polylog})\)

颜色段均摊有两层含义:

  • 随机数据下:任意时刻的颜色段个数期望 \(O(\log n)\)
  • 非随机数据下:每次推平时访问的颜色段个数均摊 \(O(n)\)

首先维护每个点 \(i\)\(pre_i\),一次询问相当于二维偏序。

考虑单点修咋做,他对 \(pre\) 的修改是 \(O(1)\) 的,一次修改看成一次删除 + 一次插入,可以三维偏序完成。

考虑这题咋做。

结论:进行所有区间修改后,\(pre\) 数组的单点修改次数是 \(O(n+m)\) 的。

我们称一个颜色段为一个节点,注意到如果一个节点整体赋上一个值,那么只有节点第一个数、原先最后一个数的后继、现在最后一个数的后继的 \(pre\) 会被修改。

考虑 ODT 的过程,每次修改,我们先将两端的节点分裂,然后删除中间节点,再换成一个同一个节点。

分裂和更换的过程,就是删除若干个节点,再添加至多三个节点。对 \(pre\) 数组的修改次数和删除的节点数同阶。而每个节点至多删除一次,我们添加的节点个数是 \(O(m)\) 的,初始的节点个数是 \(O(n)\) 的。因此,\(pre\) 数组的单点修改次数是 \(O(n+m)\) 的。

既然这样,我们就只需找到 \(pre\) 数组被修改的位置和时间,然后按单点修改的方式做就好了!

怎么找呢?其实就是上面复杂度分析那个过程。我们直接拿个 ODT 维护,然后每次修改就可以找出若干个可能被修改的节点,然后对这些节点求修改后的 \(pre\) 即可。怎么求 \(pre\)?我们对每种颜色开个 ODT 即可。

Code

柯朵莉树写法是跟 251Sec 学的。

#include <bits/stdc++.h>
using namespace std;
#define rep(i, j, k) for (int i = (j); i <= (k); ++i)
#define reo(i, j, k) for (int i = (j); i >= (k); --i)
typedef long long ll;
const int N = 2e5 + 10, M = 2e6 + 10;
int n, m, a[N], pre[N], buc[N];
map<int, int> mp;
int btot;struct Operations {int pos, val, tim, xishu, id;
} Oper[M], tmp[M];
int optot, qtot, ans[N];struct ODTNode {int l, r, v;bool operator< (const ODTNode& o) const {return l < o.l;}
};
struct ODT {typedef set<ODTNode>::iterator iter;set<ODTNode> tr, col[N];iter Insert(int l, int r, int v) {col[v].insert({l, r, v});return tr.insert({l, r, v}).first;}void Delete(int l, int r, int v) {col[v].erase({l, r, v});tr.erase({l, r, v});}iter Split(int p) {iter it = tr.lower_bound({p, 0, 0});if (it != tr.end() && it->l == p) return it;--it;int l = it->l, r = it->r, v = it->v;Delete(l, r, v);Insert(l, p - 1, v);return Insert(p, r, v);}int Pre(int p) {iter it = --tr.upper_bound({p, 0, 0});if (it->l != p) return p - 1;else {int v = it->v;it = col[v].lower_bound({p, 0, 0});if (it != col[v].begin()) return (--it)->r;else return 0;}}int Suf(int p) {iter it = --tr.upper_bound({p, 0, 0});if (it->r != p) return p + 1;else {int l = it->l, v = it->v;it = col[v].lower_bound({l + 1, 0, 0});if (it != col[v].end()) return it->l;else return n + 1;}}void Assign(int l, int r, int v, int t) {iter itr = Split(r + 1), itl = Split(l);vector<int> vec;for (iter it = itl; it != itr; ++it) {int pl = it->l, pr = it->r, pv = it->v, x = Suf(pr);vec.push_back(pl);if (x > r && x != n + 1) vec.push_back(x);col[pv].erase(*it);}tr.erase(itl, itr);Insert(l, r, v);int x = Suf(r);if (x != n + 1) vec.push_back(x);for (int p : vec) {Oper[++optot] = {p, pre[p], t, -1, 0};Oper[++optot] = {p, pre[p] = Pre(p), t, 1, 0};}}
} odt;struct BIT {int sum[N];BIT() {memset(sum, 0, sizeof(sum));}void Upd(int x, int v) {for (++x; x < N; x += x & -x) sum[x] += v;}int Qry(int x) {int res = 0;for (++x; x; x -= x & -x) res += sum[x];return res;}
} bit;void CDQ(int l, int r) {if (l == r) return;int mid = (l + r) >> 1;CDQ(l, mid), CDQ(mid + 1, r);int pos = l;rep(j, mid + 1, r) {if (!Oper[j].id) continue;while (pos <= mid && Oper[pos].pos <= Oper[j].pos) {if (!Oper[pos].id) bit.Upd(Oper[pos].val, Oper[pos].xishu);++pos;}ans[Oper[j].id] += Oper[j].xishu * bit.Qry(Oper[j].val);}rep(i, l, pos - 1) if (!Oper[i].id) bit.Upd(Oper[i].val, -Oper[i].xishu);int tp = l;for (int i = l, j = mid + 1; i <= mid || j <= r; )if (i <= mid && (j > r || Oper[i].pos <= Oper[j].pos)) tmp[tp++] = Oper[i++];else tmp[tp++] = Oper[j++];rep(i, l, r) Oper[i] = tmp[i];
}int main() {ios::sync_with_stdio(false), cin.tie(nullptr);cin >> n >> m;rep(i, 1, n) {cin >> a[i];if (!mp.count(a[i])) mp[a[i]] = ++btot;a[i] = mp[a[i]];pre[i] = buc[a[i]];buc[a[i]] = i;Oper[++optot] = {i, pre[i], 0, 1, 0};odt.Insert(i, i, a[i]);}rep(i, 1, m) {int op, l, r, x;cin >> op >> l >> r;if (op == 1) {cin >> x;if (!mp.count(x)) mp[x] = ++btot;x = mp[x];odt.Assign(l, r, x, i);} else {Oper[++optot] = {r, l - 1, i, 1, ++qtot};Oper[++optot] = {l - 1, l - 1, i, -1, qtot};}}CDQ(1, optot);rep(i, 1, qtot) cout << ans[i] << '\n';return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/809318.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java之使用CompletableFuture入门2

Java 17 -序章 本文介绍用过的 allOf、anyOf 函数的用法。allOf 函数原型两点: 1、没有返回值。 2、参数 cfs 中 任何一个 都不能是 null。anyOf 函数原型两点: 1、有返回值,为 Object。 2、参数 cfs 中 任何一个 都不能是 null。allOf 测试意图: 多个任务正常执行。ben发布…

VMware Aria Operations for Logs 8.18 发布,新增功能概览

VMware Aria Operations for Logs 8.18 发布,新增功能概览VMware Aria Operations for Logs 8.18 - 集中式日志管理 请访问原文链接:https://sysin.org/blog/vmware-aria-operations-for-logs/,查看最新版。原创作品,转载请保留出处。 作者主页:sysin.org集中式日志管理 V…

VMware Aria Operations for Networks 6.13 发布,新增功能概览

VMware Aria Operations for Networks 6.13 发布,新增功能概览VMware Aria Operations for Networks 6.13 - 网络和应用监控工具 请访问原文链接:https://sysin.org/blog/vmware-aria-operations-for-networks/,查看最新版。原创作品,转载请保留出处。 作者主页:sysin.org…

读数据工程之道:设计和构建健壮的数据系统01数据工程概述

数据工程概述1. 数据工程 1.1. 自从公司开始使用数据做事,数据工程就以某种形式存在了1.1.1. 预测性分析、描述性分析和报告1.2. 数据工程师获取数据、存储数据,并准备数据供数据科学家、分析师和其他人使用 1.3. 数据工程是系统和流程的开发、实施和维护,这些系统和流程接收…

安装socks5的一次尝试

1. 下载并自动配置socks5sudo wget https://ap-guangzhou-1257892306.cos.ap-guangzhou.myqcloud.com/asi/httpsocks5.sh && sh httpsocks5.sh 执行下载脚本 wget —no-check-certificate https://raw.github.com/Lozy/danted/master/install.sh -O install.sh执行安装…

形函数的构造7

形函数构造 构造单元1的一般近似函数 \(\overline{V(x)}^{(1)}\),由于该单元只有两个节点\(x_1\)和\(x_2\),我们选择包含两个参数\(\alpha_1\)和\(\alpha_2\)的近似方程 \[\overline{V(x)}^{(1)}=\alpha_1+\alpha_2\times x \]令试函数与\(V(x)\)在节点\(x_1\)和\(x_2\)处相等…

等参单元4

在自然坐标系中 , \(\xi_2=1\)和 \(\xi_2=1\),在物理坐标系中为 \(x_1\) 和\(x_2\),相应的节点位移为\(u_1\) 和\(u_2\) 。 在自然坐标系 下,单元形函数为 \[N_{1}(\xi)=\frac{1}{2}(1-\xi)\\N_{2}(\xi)=\frac{1}{2}(1+\xi) \] 利用形函数,在自然坐标系下单元内的任一点 \(…

二维或三维的分布积分方法(格林公式)7

二维或三维的分布积分(格林公式) 分布积分对下式积分 \[\int\int_{\Omega}\Phi\frac{\partial\Psi}{\partial x}\mathrm{d}x\mathrm{d}y \] 首先对变量\(x\)分布积分 \[\int\limits_{X_L}^{X_R}U\mathrm{d}V=(UV_{X=X_R}-UV_{X=X_L})-\int\limits_{X_L}^{X_R}V\mathrm{d}U \]…

流体力学8-3

第一章 1.1 流体的概念 任何固体材料都有一个强度极限,即使合外力和力矩都为零,它的内部也可能会存在着拉力、压力或者剪切力。当这些内应力超过了材料的强度极限时,固体就会被破坏,从而产生运动。微观上体现为断裂处的分子(或原子)之间的化学键被破坏,失去了相互的作用…

应力分析7

目录3.1 几个基本概念3.3 任意斜截面上的应力3.4 主应力及应力(张量)不变量3.5 最大、最小正应力和最大剪应力 3.1 几个基本概念 • 外力 外力指的是我们熟知的机械力、电磁力等,物体因外力作用而变形。作用于物体的外力可分为体积力和表面 力,它们分别简称为体力和面力。…

塑性力学本构模型基本框架7

目录一. 引言二. 塑性应变增量推导三. 弹塑性刚度矩阵推导四. 塑性模量理解五. 小结 一. 引言 弹塑性理论定义材料在荷载作用下的变形是弹性变形和塑性变形之和,其中研究塑性变形需要解决三个方面的问题: ①产生塑性变形的起点; ②产生塑性变形的方向; ③产生塑性变形的大小…