下面是代码,之前提交7也没卡,改了之后7也卡了
#include <iostream>
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int MAXN = 1e6 + 5;
const int MAXQ = 1e6 + 5;
int N, M;
int a[MAXN];
// 莫队
int ans[MAXQ];
// 块大小
int size;
struct Query
{
// 区间
int l, r;
// 时间戳
int t;
// 询问前的修改数量
int changes;
} query[MAXQ];
// 询问的数量
int Qtot = 0;
// 修改
struct Change
{
// 下标
int id;
// 新值
int val;
} change[MAXN];
// 修改的数量
int Ctot = 0;
bool cmp(Query a, Query b)
{
// 左端点不在同一个块内
if ((a.l / size) != (b.l / size))
return a.l < b.l;
else if (a.r != b.r)
return a.r < b.r;
else
return a.changes < b.changes;
}
int f[MAXN];
ll num = 0;
// 区间移动
void del(int x)
{
f[a[x]]--;
if (f[a[x]] == 0)
num--;
}
void add(int x)
{
f[a[x]]++;
if (f[a[x]] == 1)
num++;
}
void tupdate(int x)
{
f[a[change[x].id]]--;
if (f[a[change[x].id]] == 0)
num--;
f[change[x].val]++;
if (f[change[x].val] == 1)
num++;
}
int main()
{
// 数据读取
cin >> N >> M;
size = sqrt(N);
for (int i = 1; i <= N; i++)
cin >> a[i];
for (int i = 1; i <= M; i++)
{
char c;
int x, y;
cin >> c >> x >> y;
if (c == 'Q')
{
Qtot++;
query[Qtot].l = x;
query[Qtot].r = y;
query[Qtot].t = Qtot;
query[Qtot].changes = Ctot;
}
else
{
Ctot++;
change[Ctot].id = x;
change[Ctot].val = y;
}
}
// 当前区间
int x = 1, y = 0;
// 当前已经处理修改数量
int modify = 0;
// 排序
sort(query + 1, query + Qtot + 1, cmp);
// 处理每次的询问
for (int i = 1; i <= Qtot; i++)
{
// 正常莫队修改
while (y < query[i].r)
add(++y);
while (x > query[i].l)
add(--x);
while (y > query[i].r)
del(y--);
while (x < query[i].l)
del(x++);
// 增加时间维修改
while (modify < query[i].changes)
{
modify++;
if (change[modify].id <= query[i].r && change[modify].id >= query[i].l)
tupdate(modify);
swap(a[change[modify].id], change[modify].val);
}
while (modify > query[i].changes)
{
if (change[modify].id <= query[i].r && change[modify].id >= query[i].l)
tupdate(modify);
swap(a[change[modify].id], change[modify].val);
modify--;
}
ans[query[i].t] = num;
}
for (int i = 1; i <= Qtot; i++)
cout << ans[i] << endl;
return 0;
}