莫队算法 Gym - 100496D Data Mining

 

题目传送门

 1 /*  2  题意:从i开始,之前出现过的就是之前的值,否则递增,问第p个数字是多少  3  莫队算法:先把a[i+p-1]等效到最前方没有它的a[j],问题转变为求[l, r]上不重复数字有几个,裸莫队:)  4 */  5 #include <cstdio>  6 #include <algorithm>  7 #include <map>  8 #include <set>  9 #include <vector>  10 #include <cmath>  11 #include <cstring>  12 using namespace std;  13  14 const int MAXN = 2e6 + 10;  15 const int INF = 0x3f3f3f3f;  16 map<int, int> table;  17 vector<int> V[MAXN];  18 int cnt[MAXN];  19 int a[MAXN];  20 int ans[MAXN];  21 struct Data  22 {  23 int b, l, r, id;  24  Data () {}  25 Data (int b, int l, int r, int id) : b (b), l (l), r (r), id (id) {};  26 }data[MAXN];  27 int n, m;  28 int ret;  29  30 bool cmp(Data x, Data y)  31 {  32 if (x.b == y.b) return x.r < y.r;  33 else return x.b < y.b;  34 }  35  36 void updata(int v)  37 {  38 if (v == 1) ret++;  39 else if (v == 0) ret--;  40 }  41  42 void Modui(void)  43 {  44 sort (data+1, data+1+m, cmp);  45 memset (cnt, 0, sizeof (cnt));  46  47 int l = 1, r = 0; ret = 0;  48 for (int i=1; i<=m; ++i)  49  {  50 while (data[i].l < l)  51  {  52 ++cnt[a[--l]];  53 if (cnt[a[l]] == 1) ret++;  54  }  55 while (data[i].l > l)  56  {  57 --cnt[a[l]];  58 if (cnt[a[l]] == 0) ret--;  59 l++;  60  }  61 while (data[i].r > r)  62  {  63 ++cnt[a[++r]];  64 if (cnt[a[r]] == 1) ret++;  65  }  66 while (data[i].r < r)  67  {  68 --cnt[a[r]];  69 if (cnt[a[r]] == 0) ret--;  70 r--;  71  }  72  73 ans[data[i].id] = ret;  74  }  75  76 for (int i=1; i<=m; ++i)  77  {  78 printf ("%d\n", ans[i]);  79  }  80 }  81  82 int main(void) //Gym - 100496D Data Mining  83 {  84 // freopen ("D.in", "r", stdin);  85 freopen ("data.in", "r", stdin);  86 freopen ("data.out", "w", stdout);  87  88 while (scanf ("%d", &n) == 1)  89  {  90  table.clear ();  91 for (int i=1; i<=n; ++i) V[i].clear ();  92  93 int num = 0;  94 for (int i=1; i<=n; ++i)  95  {  96 scanf ("%d", &a[i]);  97 a[i] = table[a[i]] ? table[a[i]] : table[a[i]] = ++num;  98  V[a[i]].push_back (i);  99  } 100 101 int block = (int) sqrt (n * 1.0); 102 scanf ("%d", &m); 103 for (int i=1; i<=m; ++i) 104  { 105 int l, r; scanf ("%d%d", &l, &r); 106 r = l + r - 1; 107 int pos = lower_bound (V[a[r]].begin (), V[a[r]].end (), l) - V[a[r]].begin (); 108 r = V[a[r]][pos]; 109 data[i] = Data (l / block, l, r, i); 110  } 111 112  Modui (); 113  } 114 115 return 0; 116 }

 

你可能感兴趣的:(data mining)