莫队水过
每次修改之间的询问用莫队搞一下,还挺快……
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <map>
using namespace std;
#define MAXN 100003
#define MAXQ 100003
int n, a[MAXN], sqrtn;
struct Qtype
{
int num;
char opt;
int x, y;
} qy[MAXQ];
bool cmp(const Qtype &a, const Qtype &b)
{
int ax = a.x / sqrtn, bx = b.x / sqrtn;
if (ax != bx)
return ax < bx;
return a.y < b.y;
}
map<int, int> lisan;
int lct = 0;
int ct[MAXN], ans[MAXN];
void work(int ql, int qr)
{
int l, r, m;
l = r = m = 0;
memset(ct, 0, sizeof(ct));
for (int i = ql; i < qr; ++i)
qy[i].num = i - ql;
sort(qy + ql, qy + qr, cmp);
for (int i = ql; i < qr; ++i)
{
while (l < qy[i].x)
{
if (--ct[a[l]] == 0)
--m;
++l;
}
while (l > qy[i].x)
{
--l;
if (++ct[a[l]] == 1)
++m;
}
while (r < qy[i].y)
{
if (++ct[a[r]] == 1)
++m;
++r;
}
while (r > qy[i].y)
{
--r;
if (--ct[a[r]] == 0)
--m;
}
ans[qy[i].num] = m;
}
for (int i = ql; i < qr; ++i)
printf("%d\n", ans[i - ql]);
}
int main()
{
int Q;
scanf("%d%d", &n, &Q);
sqrtn = sqrt(n);
for (int i = 0; i < n; ++i)
scanf("%d", &a[i]);
for (int i = 0; i < Q; ++i)
{
scanf(" %c%d%d", &qy[i].opt, &qy[i].x, &qy[i].y);
--qy[i].x;
}
for (int i = 0; i < n; ++i)
{
map<int, int>::iterator it = lisan.find(a[i]);
if (it == lisan.end())
{
lisan[a[i]] = lct;
a[i] = lct++;
}
else
a[i] = it->second;
}
for (int i = 0; i < Q; ++i)
if (qy[i].opt == 'R')
{
map<int, int>::iterator it = lisan.find(qy[i].y);
if (it == lisan.end())
{
lisan[qy[i].y] = lct;
qy[i].y = lct++;
}
else
qy[i].y = it->second;
}
int last = 0;
for (int i = 0; i <= Q; ++i)
if (i == Q)
work(last, i);
else if (qy[i].opt == 'R')
{
work(last, i);
a[qy[i].x] = qy[i].y;
last = i + 1;
}
return 0;
}