博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
CF940F Machine Learning
阅读量:4958 次
发布时间:2019-06-12

本文共 2306 字,大约阅读时间需要 7 分钟。

给定一个序列 \(a_i\)\(m\) 次操作:

  • 单点修
  • 询问区间每个数出现次数的 \(\operatorname{mex}\)

\(a_i\in[1,\ 10^9],\ n,\ m\leq10^5\)

带修莫队


凭借 \(4s\) 的时限, \(CF\) 神仙评测机, \(O(n^{\frac{3}{5}})\) 是可以轻松过 \(10^5\) 的……

\(trick:\) 易知答案是 \(\sqrt n\) 级别的,因此不用值域分块,直接暴力即可……

时间复杂度 \(O(n\sqrt n+m\sqrt n)\)

代码

#include 
using namespace std;const int maxn = 1e5 + 10;int n, m, bsz, qtot, utot, a[maxn], lst[maxn], bl[maxn], ans[maxn], c[maxn << 1], cnt[maxn << 1];struct Update { int pos, pre, nxt;} U[maxn];struct Query { int l, r, t, tid; bool operator < (const Query& o) const { return bl[l] == bl[o.l] ? bl[r] == bl[o.r] ? t < o.t : r < o.r : l < o.l; }} Q[maxn];void discretion() { #define get_val(x) (lower_bound(data + 1, data + tot + 1, x) - data) static int tot, data[maxn << 1]; for (int i = 1; i <= n; i++) { data[i] = a[i]; } for (int i = 1; i <= utot; i++) { data[n + i] = U[i].nxt; } tot = n + utot; sort(data + 1, data + tot + 1); tot = unique(data + 1, data + tot + 1) - data - 1; for (int i = 1; i <= n; i++) { a[i] = get_val(a[i]); } for (int i = 1; i <= utot; i++) { U[i].pre = get_val(U[i].pre); U[i].nxt = get_val(U[i].nxt); }}void upd(int x, int v) { cnt[c[x]]--, cnt[c[x] += v]++;}void update(int t, int l, int r, int op) { int p = U[t].pos, x = op ? U[t].pre : U[t].nxt; if (l <= p && p <= r) { upd(a[p], -1), upd(x, 1); } a[p] = x;}int main() { scanf("%d %d", &n, &m); bsz = pow(n, 0.666666); for (int i = 1; i <= n; i++) { scanf("%d", a + i); lst[i] = a[i]; bl[i] = (i - 1) / bsz + 1; } for (int i = 1; i <= m; i++) { int op, x, y; scanf("%d %d %d", &op, &x, &y); if (op == 1) { Q[++qtot] = Query{x, y, utot, qtot}; } else { U[++utot] = Update{x, lst[x], y}, lst[x] = y; } } discretion(); cnt[0] = n << 1; int l = 1, r = 0, now = 0; sort(Q + 1, Q + qtot + 1); for (int i = 1; i <= qtot; i++) { while (l > Q[i].l) upd(a[--l], 1); while (r < Q[i].r) upd(a[++r], 1); while (l < Q[i].l) upd(a[l++], -1); while (r > Q[i].r) upd(a[r--], -1); while (now < Q[i].t) update(++now, l, r, 0); while (now > Q[i].t) update(now--, l, r, 1); while (cnt[ans[Q[i].tid]]) ans[Q[i].tid]++; } for (int i = 1; i <= qtot; i++) { printf("%d\n", ans[i]); } return 0;}

转载于:https://www.cnblogs.com/Juanzhang/p/10653005.html

你可能感兴趣的文章
使用vue和web3创建你的第一个以太坊APP
查看>>
coursera 算法二 week 1 wordnet
查看>>
下一个研究主题:需求变更流程
查看>>
转 Objective-C中不同方式实现锁(二)
查看>>
Available Date 相关
查看>>
MySQL索引
查看>>
.Net中的AutoScrollPosition问题 (panel 滚动条的位置设定)
查看>>
archlinux安装输入法需要的包及archlinux无法使用输入法的解决
查看>>
BZOJ 1251: 序列终结者
查看>>
ArcGIS API for JavaScript 4.2学习笔记[18] 搜索小部件
查看>>
callback in C
查看>>
Android学习笔记
查看>>
Win32隐藏输出console窗口
查看>>
英语----不可小看的冠词
查看>>
Tomcat 安装以及配置
查看>>
02. Pandas 1|数据结构Series、Dataframe
查看>>
CSS优化技巧7则
查看>>
数据库常见面试题(1)
查看>>
美图秀秀的效果
查看>>
开发进度4
查看>>