主席树求区间内不同数字的个数

题目描述

如题,主席树求区间内不同数字的个数

(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]));
	}
}
原文地址:https://www.cnblogs.com/leiyuanze/p/13963397.html