Welcome To Ke_scholar's |

Ke_scholar

园龄:2年1个月粉丝:30关注:10

带修莫队模板

取分块大小 \(n^\frac{2}{3}\) 最优。
例题:数颜色

#include<bits/stdc++.h>
using namespace std;
using i64 = long long;
const int N = 1e6 + 5;
int cnt[N], a[N];
struct query {
int l, r, t, id;//加入时间戳
};
struct modfiy {
int pos, val;
};
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, m;
cin >> n >> m;
int M = pow(n, 2.0 / 3.0);
for (int i = 1; i <= n; i ++)
cin >> a[i];
int cntc = 0, cntq = 0;
vector<query> q;
vector<modfiy> c;
for (int i = 0; i < m; i ++) {
char op;
int l, r;
cin >> op >> l >> r;
if (op == 'Q') {
int qt = c.size();
q.push_back({l, r, qt, (int)q.size()});
} else {
c.push_back({l, r});
}
}
//排序与普通莫队不同
sort(q.begin(), q.end(), [&M](query x, query y) {
return (((x.l / M) ^ (y.l / M)) ? x.l < y.l : ((x.r / M) ^ (y.r / M)) ? x.r < y.r : x.t < y.t);
});
int l = 1, r = 0, time = 0, now = 0;
vector<int> ans(q.size());
for (int i = 0; i < q.size(); i ++) {
auto [ql, qr, qt, id] = q[i];
while (l < ql) now -= !--cnt[a[l++]];
while (l > ql) now += !cnt[a[--l]]++;
while (r < qr) now += !cnt[a[++r]]++;
while (r > qr) now -= !--cnt[a[r--]];
while (time < qt) {
if (ql <= c[time].pos && c[time].pos <= qr)
now -= !--cnt[a[c[time].pos]] - !cnt[c[time].val]++;
swap(a[c[time].pos], c[time].val);
++time;
}
while (time > qt) {
--time;
if (ql <= c[time].pos && c[time].pos <= qr)
now -= !--cnt[a[c[time].pos]] - !cnt[c[time].val]++;
swap(a[c[time].pos], c[time].val);
}
ans[id] = now;
}
for (int i = 0; i < q.size(); i ++)
cout << ans[i] << "\n";
return 0;
}

本文作者:Ke_scholar

本文链接:https://www.cnblogs.com/Kescholar/p/18307062

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   Ke_scholar  阅读(12)  评论(0编辑  收藏  举报
历史上的今天:
2023-07-17 第五次作业题解
2023-07-17 SMU Summer 2023 Contest Round 4
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起