题意简述
给定一个序列
给出多个询问(l,r),求出l~r有多少不同的数字
题解思路
莫队,注意要奇偶块排序
代码
#include <cmath>
#include <cstdio>
#include <cctype>
#include <algorithm>
using namespace std;
struct Node
{
int l, r, i;
} q[500100];
int n, m, len, ll, lr, s;
int a[500100], num[500100], c[1000100], ans[500100];
const int ri_top = 2e7;
char ri[ri_top], *rich = ri;
void read_int(int &x)
{
while (!isdigit(*rich)) ++rich;
for (x = *rich - '0'; isdigit(*++rich); x = x * 10 + *rich - '0');
}
const int wi_top = 2e7;
char wi[wi_top], *wich = wi;
const int wi_top1 = 11;
char wi1[wi_top1], *wich1 = wi1;
void write_int(int x)
{
if (!x) {*wich++ = '0'; return;}
for (; x; *wich1++ = x % 10 + '0', x /= 10);
while (wi1 != wich1) *wich++ = *--wich1;
}
struct _
{
__inline__ __attribute((always_inline)) bool operator()(const Node& x, const Node& y)
{
return num[x.l] < num[y.l] || num[x.l] == num[y.l] && ((num[x.l] & 1) ? x.r < y.r : x.r > y.r);
}
}cmp;
int main()
{
fread(ri, 1, ri_top, stdin);
read_int(n);
len = sqrt(n);
for (register int i = 1; i <= n; ++i)
{
read_int(a[i]);
num[i] = (i - 1) / len + 1;
}
read_int(m);
for (register int i = 1; i <= m; ++i)
{
read_int(q[i].l);
read_int(q[i].r);
q[i].i = i;
}
sort(q + 1, q + m + 1, cmp);
for (register int i = 1; i <= m; ++i)
{
int l = q[i].l, r = q[i].r;
while (l < ll) s += !(c[a[--ll]]++);
while (r > lr) s += !(c[a[++lr]]++);
while (l > ll) s -= !(--c[a[ll++]]);
while (r < lr) s -= !(--c[a[lr--]]);
ans[q[i].i] = s;
}
for (register int i = 1; i <= m; ++i)
write_int(ans[i]), *wich++ = '
';
fwrite(wi, 1, wich - wi, stdout);
}