/* The MO team algorithm is an off-line algorithm, used to solve the problem of known l,r ask you l,r inside the value of the order of the block, the following block through the front of the block left to move to the right, so there may be a situation can get O (1) or lower complexity of the order when divided by Good n (? The question test instructions: How many different numbers are asked in the range from L to R, ask a lot */#include <cstdio> #include <cstring> #include <algorithm> #include <map> #include <cmath> #include <vector>using namespace std;const int MAX = 2000000 + 10;int A[max];map & Lt;int, int> table;int res[max];int ans[max];int N, m;vector<int> g[max];int unit;struct edge{int L, r, id;} B[max];bool CMP (Edge I, Edge j) {if (I.l/unit = = j.l/unit) {return i.r/unit < J.r/unit; } return I.l/unit < J.l/unit;} void Modui () {sort (b + 1, B + M + 1, CMP); memset (res, 0, sizeof (RES)); int L = 1, r = 0, ret = 0; for (int i = 1, i <= m; i++) {while (L < B[I].L) {Res[a[l]]--; if (res[a[l]] = = 0) ret--; l++; }//L is not, then the number is less one, if the number becomes 0, indicating that the original added the number, the total decrease of 1 while (L > B[i].l) {res[a[--l]]++; if (res[a[l]] = = 1) ret++;}//L is, then L-1 is also (L>B[I].L) description L less than 1 may be the threshold value, if it becomes 1, indicating a number while (R < B[I].R) {res[a[++r]]++; if (res[a[r]] = = 1) ret++; } while (R > B[I].R) {res[a[r]]--; if (res[a[r]] = = 0) ret--; r--; } Ans[b[i].id] = ret; Block number} for (int i = 1; I <= m; i++) printf ("%d\n", Ans[i]);} int main () {freopen ("data.in", "R", stdin), Freopen ("Data.out", "w", stdout); while (~SCANF ("%d", &n)) {int num = 0; Table.clear (); for (int i = 1; I <= n; i++) g[i].clear (); for (int i = 1; I <= n; i++) {scanf ("%d", &a[i]); A[i] = Table[a[i]]? Table[a[i]]: table[a[i]] = ++num;//discretization//If TABLE[A[I]] has a value, then a[i] = Table[a[i]], equivalent to the number, if not, then push backwards g[a[i]].pu Sh_back (i);//The position of the individual numbers that record the value a[i]} unit = (int) sqrt (1.0*n); scanf ("%d", &m); int L, R; for (int i = 1; I <= m;i++) {scanf ("%d%d", &l, &r); R = L + r-1; int pos = Lower_bound (G[a[r]].begin (), G[a[r]].end (), L)-g[a[r]].begin ();//two points to get R again L on the right of the first occurrence of position r = G[a[r]][pos]; B[I].L = l; B[I].R = R; B[i].id = i; } modui (); } return 0;}
2011-2012 Winter Petrozavodsk Camp, Andrew Stankevich Contest (ASC 41)-Mo team Algorithm--data Mining