Educational Codeforces Round 22 E. Army Creation 主席树
链接:
http://codeforces.com/contest/813/problem/E
题意:
给你一个长度问n的数组,每次讯问一段区间l,r,问最多可以选多少个数字使得每个数字出现的次数不超过k
题解:
使用主席树即可,具体看代码
代码:
31 struct Node { int l, r, sum; }; 32 int n, k, q; 33 int a[MAXN], b[MAXN]; 34 VI G[MAXN]; 35 Node T[MAXN * 50]; 36 int rt[MAXN], cnt; 37 38 void update(int l, int r, int &x, int y, int pos, int val) { 39 T[++cnt] = T[y], T[cnt].sum += val, x = cnt; 40 if (l == r) return; 41 int m = (l + r) >> 1; 42 if (pos <= m) update(l, m, T[x].l, T[y].l, pos, val); 43 else update(m + 1, r, T[x].r, T[y].r, pos, val); 44 } 45 46 int query(int l, int r, int x, int L, int R) { 47 if (L <= l && r <= R) return T[x].sum; 48 int m = (l + r) >> 1; 49 int ret = 0; 50 if (L <= m) ret += query(l, m, T[x].l, L, R); 51 if (R > m) ret += query(m + 1, r, T[x].r, L, R); 52 return ret; 53 } 54 55 int main() { 56 ios::sync_with_stdio(false), cin.tie(0); 57 cin >> n >> k; 58 rep(i, 1, n + 1) cin >> a[i], G[a[i]].pb(i); 59 rep(i, 1, MAXN) if (G[i].size() > k) rep(j, k, G[i].size()) b[G[i][j]] = G[i][j - k]; 60 rep(i, 1, n + 1) { 61 update(1, n, rt[i], rt[i - 1], i, 1); 62 if (b[i]) update(1, n, rt[i], rt[i], b[i], -1); 63 } 64 cin >> q; 65 int last = 0; 66 while (q--) { 67 int l, r; 68 cin >> l >> r; 69 l = (l + last) % n + 1; 70 r = (r + last) % n + 1; 71 if (l > r) swap(l, r); 72 last = query(1, n, rt[r], l, r); 73 cout << last << endl; 74 } 75 return 0; 76 }