主席樹求區間內不同數字的個數
阿新 • • 發佈:2020-11-12
題目描述
如題,席樹求區間內不同數字的個數
\(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\n" , query(1 , n , l , rt[r])); } }