Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- using namespace std;
- struct Tree {
- vector<int> f;
- Tree(int size = 0): f(size) {}
- int get(int pos) {
- int sum = 0;
- for (; pos >= 0; pos = (pos & (pos + 1)) - 1)
- sum += f[pos];
- return sum;
- }
- int get(int l, int r) {
- return get(r) - get(l - 1);
- }
- void upd(int pos, int delta) {
- for (; pos < f.size(); pos = (pos | (pos + 1)))
- f[pos] += delta;
- }
- };
- const int N = 50 * 1000 + 10;
- const int BLOCK = 2000;
- int a[N];
- char type[N];
- int l[N];
- int r[N];
- int n;
- int m;
- int ans[N];
- vector<int> atL[N];
- vector<int> atId[N];
- set<int> seen[N];
- void solveBlock(int pos) {
- int last = min(m, pos + BLOCK);
- vector<int> have;
- for (int i = 0; i < n; i++) {
- atL[i].clear();
- atId[i].clear();
- }
- for (int i = 0; i < 2 * BLOCK; i++)
- seen[i].clear();
- for (int i = pos; i < last; i++)
- if (type[i] == 'M') {
- have.push_back(a[l[i]]);
- have.push_back(r[i]);
- } else {
- r[i]--;
- if (l[i] <= r[i]) {
- atL[r[i]].push_back(l[i]);
- atId[r[i]].push_back(i);
- }
- }
- sort(have.begin(), have.end());
- have.resize(unique(have.begin(), have.end()) - have.begin());
- for (int i = 0; i < n; i++) {
- int p = lower_bound(have.begin(), have.end(), a[i]) - have.begin();
- if (p != have.size() && have[p] == a[i])
- seen[p].insert(i);
- }
- for (int i = pos; i < last; i++) {
- if (type[i] == 'M') {
- int old = a[l[i]];
- int cur = r[i];
- int p = l[i];
- int pOld = lower_bound(have.begin(), have.end(), old) - have.begin();
- int pCur = lower_bound(have.begin(), have.end(), cur) - have.begin();
- seen[pOld].erase(p);
- seen[pCur].insert(p);
- a[p] = cur;
- } else {
- for (int p = 0; p < have.size(); p++) {
- auto it = seen[p].lower_bound(l[i]);
- if (it != seen[p].end() && *it <= r[i])
- ans[i]++;
- }
- }
- }
- map<int, int> pred;
- Tree tree(n);
- for (int i = 0; i < n; i++) {
- if (!binary_search(have.begin(), have.end(), a[i])) {
- if (pred.count(a[i]))
- tree.upd(pred[a[i]], -1);
- pred[a[i]] = i;
- tree.upd(i, 1);
- }
- for (int j = 0; j < atL[i].size(); j++) {
- int L = atL[i][j];
- int id = atId[i][j];
- ans[id] += tree.get(L, i);
- }
- }
- }
- int main() {
- scanf("%d%d", &n, &m);
- for (int i = 0; i < n; i++)
- scanf("%d", &a[i]);
- for (int i = 0; i < m; i++) {
- while (type[i] != 'M' && type[i] != 'Q')
- scanf("%c", &type[i]);
- scanf("%d%d", &l[i], &r[i]);
- }
- for (int i = 0; i < m; i += BLOCK)
- solveBlock(i);
- for (int i = 0; i < m; i++)
- if (type[i] == 'Q')
- printf("%d\n", ans[i]);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement