题目描述
如题,主席树求区间内不同数字的个数
(Code)
#include<cstdio>
#include<cstring>
using namespace std;
const int N = 1e6 + 5;
int n , m , a[N] , la[N] , rt[N] , size;
struct segment{
int s , ls , rs;
}seg[N << 5];
inline int read()
{
char ch = getchar(); int res = 0;
while (ch < '0' || ch > '9') ch = getchar();
while (ch >= '0' && ch <= '9')
res = (res << 3) + (res << 1) + ch - '0' , ch = getchar();
return res;
}
inline int update(int l , int r , int x , int v , int pre)
{
int o = ++size; seg[o] = seg[pre] , seg[o].s += v;
if (l == r) return o;
int mid = (l + r) >> 1;
if (x <= mid) seg[o].ls = update(l , mid , x , v , seg[pre].ls);
else seg[o].rs = update(mid + 1 , r , x , v , seg[pre].rs);
return o;
}
inline int query(int l , int r , int x , int pre)
{
if (l == r) return seg[pre].s;
int mid = (l + r) >> 1;
if (x <= mid) return query(l , mid , x , seg[pre].ls) + seg[seg[pre].rs].s;
else return query(mid + 1 , r , x , seg[pre].rs);
}
int main()
{
memset(la , 255 , sizeof la);
n = read();
for(register int i = 1; i <= n; i++)
{
a[i] = read();
if (la[a[i]] == -1) rt[i] = update(1 , n , i , 1 , rt[i - 1]);
else {
int pre = update(1 , n , la[a[i]] , -1 , rt[i - 1]);
rt[i] = update(1 , n , i , 1 , pre);
}
la[a[i]] = i;
}
m = read();
int l , r;
while (m--)
{
l = read() , r = read();
printf("%d
" , query(1 , n , l , rt[r]));
}
}