#include <iostream> #include <map> #include <cstdio> #include <cstring> #include <algorithm >using namespace Std;const int maxn = 30010,maxlog = 20;struct chairtree{int l,r; int ans;} Ct[maxn*maxlog];int ctroot[maxn];int cttop;int num[maxn],tnum[maxn],pre[maxn];int CreatNewNode () {CT[CTTOP].L = -1,ct [CTTOP].R =-1; Ct[cttop].ans = 0; return cttop++;} void Initzerolayer (int &root,int l,int r) {root = Creatnewnode (); if (L = = r) return; int mid = (l+r) >>1; Initzerolayer (Ct[root].l,l,mid); Initzerolayer (ct[root].r,mid+1,r);} int BS (int l,int r,int x) {int mid; while (L <= R) {mid = (l+r) >>1; if (tnum[mid] = = x) return mid; if (Tnum[mid] < x) L = mid+1; else R = mid-1; } return-1;} void pushup (int root) {Ct[root].ans = Ct[ct[root].l].ans + Ct[ct[root].r].ans;} void Update (int pre,int &root,int l,int r,int goal,int info) {if (root = =-1 | | Root = = Pre) {root = Creatnewnode (); Ct[root].ans = Ct[pre].ans; } if (L = = R) {Ct[root].ans + = info; return; } int mid = (l+r) >>1; If (goal <= mid) {if (CT[ROOT].R = =-1) CT[ROOT].R = CT[PRE].R; Update (Ct[pre].l,ct[root].l,l,mid,goal,info); } else {if (CT[ROOT].L = =-1) ct[root].l = CT[PRE].L; Update (Ct[pre].r,ct[root].r,mid+1,r,goal,info); } pushup (root);} void initct (int n) {memset (pre,-1,sizeof (pre)); Sort (tnum+1,tnum+n+1); int site,tn,i; for (tn = 1,i = 2;i <= n; ++i) if (tnum[i]! = Tnum[tn]) tnum[++tn] = Tnum[i]; memset (ctroot,-1,sizeof (ctroot)); cttop = 0; Initzerolayer (Ctroot[0],1,n); for (i = 1;i <= n; ++i) {site = BS (1,tn,num[i]); if (pre[site] = =-1) Update (ctroot[i-1],ctroot[i],1,n,i,1); else {Update (ctroot[i-1],ctroot[i],1,n,pre[site],-1); Update (ctroot[i-1],ctroot[i],1,n,i,1); } Pre[site] = i; }}int Query (int root,int goal,int l,int R) {if (goal = = L) return Ct[root].ans; int mid = (l+r) >>1; if (mid+1 <= goal) return Query (CT[ROOT].R,GOAL,MID+1,R); Return Query (ct[root].l,goal,l,mid) + Ct[ct[root].r].ans;} int main () {int i,l,r,q,n; while (scanf ("%d", &n)! = EOF) {for (i = 1;i <= n; ++i) {scanf ("%d", &num[i]); Tnum[i] = Num[i]; } INITCT (n); scanf ("%d", &q); while (q--) {scanf ("%d%d", &l,&r); printf ("%d\n", Query (Ctroot[r],l,1,n)); }} return 0;}
SPOJ number of different numbers in Dquery interval chairman tree