数颜色 / 维护队列
题目大意
要你维护一个序列,可能会改变一个位置的数,还有询问一个区间内有多少种数。
思路
这道题有多种做法,然后我们考虑用带修莫队来做。
莫队是两个指针第一个按块搞,第二个就按个搞。
那我们带修的话我们就可以加上一个时间指针。
那也是一个道理,我们就也是分成块,然后第一个排序按左边的块排,第二个排序按右边的块排,接着就按着时间排。
然后就每次三个指针移动一下就可以了。
然后至于时间指针的移动,把位置 x 的 a 换成 b,就相当于把 a 的贡献消除,加上 b 的贡献。
然后就差不多了,我们最优会选取 n23 的长度,这样复杂度是 n53 的。、
(搞这个长度直接用 pow 函数)
代码
#include<cmath>
#include<cstdio>
#include<algorithm>
using namespace std;
struct node {
int t, x, y, num, ans;
}a[140001];
int n, m, x, y, block[140001], t, col[140001];
int fr[140001], to[140001], lst[140001], sz;
int q, tim, pl[140001], num[1000001], ans;
bool in[140001];
char op;
bool cmp(node x, node y) {
if (block[x.x] != block[y.x]) return block[x.x] < block[y.x];
if (block[x.y] != block[y.y]) return block[x.y] < block[y.y];
return x.t < y.t;
}
void clac(int p) {
if (in[p]) {
num[col[p]]--;
if (!num[col[p]]) ans--;
}
else {
num[col[p]]++;
if (num[col[p]] == 1) ans++;
}
in[p] ^= 1;
}
void change(int p, int t) {
if (in[p]) {
clac(p);
col[p] = t;
clac(p);
}
else col[p] = t;
}
bool cmp1(node x, node y) {
return x.num < y.num;
}
int main() {
scanf("%d %d", &n, &m);
for (int i = 1; i <= n; i++) {
scanf("%d", &lst[i]);
col[i] = lst[i];
}
sz = pow(n, 2.0 / 3);
for (int i = 1; i <= n; i++)
block[i] = (i - 1) / sz + 1;
for (int i = 1; i <= m; i++) {
op = getchar();
while (op != 'Q' && op != 'R') op = getchar();
if (op == 'Q') {
scanf("%d %d", &x, &y);
a[++q] = (node){tim, x, y, i, 0};
}
else {
scanf("%d %d", &x, &y);
pl[++tim] = x;
fr[tim] = lst[x];
to[tim] = y;
lst[x] = y;
}
}
sort(a + 1, a + q + 1, cmp);
t = 0; x = 1; y = 0;
for (int i = 1; i <= q; i++) {
while (t < a[i].t) t++, change(pl[t], to[t]);
while (t > a[i].t) change(pl[t], fr[t]), t--;
while (x < a[i].x) clac(x), x++;
while (x > a[i].x) x--, clac(x);
while (y < a[i].y) y++, clac(y);
while (y > a[i].y) clac(y), y--;
a[i].ans = ans;
}
sort(a + 1, a + q + 1, cmp1);
for (int i = 1; i <= q; i++) printf("%d\n", a[i].ans);
return 0;
}
__EOF__
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现