这个wa有一个很神奇的性质,每一个点错误的数字都是比答案数字少1(
ai是颜色
我们发现只要 prei(位置 i 的上一个颜色相同的位置)小于 l ,那么该位置的颜色就是第一次在 [l,r] 区间中出现的。
然后这题的做法可以转化为教主的魔法类似的做法
lower_bound,在 l 之前的都是答案set数组,对于每种颜色存放该颜色的位置--lower_bound和upper_bound来在set数组中快速找到修改后颜色的前驱和后继,从而进行插入操作#include <bits/stdc++.h>
#define int long long
#define endl "\n"
using namespace std;
constexpr const int RANGE = 1e6 + 1;
constexpr const int N = 1.4e5;
string opt;
int n, m, l, r, block, tot;
int a[N], pre[N], nxt[N], L[N], R[N], srt[N], be[N];
set<int> has[RANGE];
void solve() {
cin >> n >> m;
for (int i = 1; i <= n; ++i) cin >> a[i];
block = sqrt(n), tot = (n + block - 1) / block;
auto rb = [&](int k) {
for (int i = L[k]; i <= R[k]; ++i) srt[i] = pre[i];
sort(srt + L[k], srt + R[k] + 1);
};
// memset(nxt, 0x7f, sizeof nxt);
for (int i = 1; i <= tot; ++i) {
L[i] = (i - 1) * block + 1; R[i] = min(n, i * block);
for (int j = L[i]; j <= R[i]; ++j) {
be[j] = i;
// if (not has[a[j]].empty()) pre[j] = *has[a[j]].rbegin();
// else pre[j] = 0;
has[a[j]].insert(0);
pre[j] = *has[a[j]].rbegin();
has[a[j]].insert(j);
nxt[pre[j]] = j;
}
rb(i);
}
for (int _ = 1; _ <= m; ++_) {
cin >> opt >> l >> r;
if (opt[0] == 'Q') {
int ans = 0;
for (int i = l; i <= min(r, R[be[l]]); ++i) if (pre[i] < l) ++ans;
if (be[l] != be[r])
for (int i = L[be[r]]; i <= r; ++i) if (pre[i] < l) ++ans;
for (int i = be[l] + 1; i <= be[r] - 1; ++i)
ans += lower_bound(srt + L[i], srt + R[i] + 1, l) - srt - L[i];
cout << ans << endl;
} else {
pre[nxt[l]] = pre[l];
nxt[pre[l]] = nxt[l];
has[a[l]].erase(l);
a[l] = r;
has[r].insert(0);
// for (auto v : has[r]) cout << v << " "; cout << endl;
int preid = *(--lower_bound(has[r].begin(), has[r].end(), l));
int nxtid = *upper_bound(has[r].begin(), has[r].end(), l);
has[r].insert(l);
pre[l] = preid; nxt[l] = nxtid;
nxt[preid] = l; pre[nxtid] = l;
rb(be[l]); rb(be[preid]); rb(be[nxtid]);
// cout << preid << " " << nxtid << endl;
// for (int i = 1; i <= n; ++i) cout << pre[i] << " "; cout << endl;
// for (int i = 1; i <= n; ++i) cout << nxt[i] << " "; cout << endl;
}
}
}
signed main() {
std::cin.tie(nullptr) -> sync_with_stdio(false);
solve();
}