1+ /*
2+ Submission link - https://cses.fi/problemset/result/15829712/
3+
4+ TC - o((N + Q) log(N+Q) )
5+ SC - O(N + Q)
6+
7+ Approach (Simple & Short):
8+
9+ Compress salary values since they can be as large as 10^9.
10+ Use a Fenwick Tree to store and manage salary frequencies.
11+ On updates, reduce the count of the old salary and increase the new one.
12+ For range queries, get the answer using prefix sums from the Fenwick Tree.
13+
14+ */
15+
16+
17+ #include < bits/stdc++.h>
18+ using namespace std ;
19+ const int N = 600005 ;
20+ int n, q;
21+ int cur_p[200005 ];
22+ int t[N];
23+ struct Query {
24+ int type, a, b;
25+ } qs[200005 ];
26+
27+ void add (int i, int v) {
28+ for (; i < N; i += i & -i) t[i] += v;
29+ }
30+
31+ int sum (int i) {
32+ int s = 0 ;
33+ for (; i > 0 ; i -= i & -i) s += t[i];
34+ return s;
35+ }
36+
37+ int main () {
38+ ios::sync_with_stdio (0 ); cin.tie (0 );
39+ cin >> n >> q;
40+ vector<int > coords;
41+ for (int i = 1 ; i <= n; i++) {
42+ cin >> cur_p[i];
43+ coords.push_back (cur_p[i]);
44+ }
45+ for (int i = 0 ; i < q; i++) {
46+ char op; cin >> op;
47+ cin >> qs[i].a >> qs[i].b ;
48+ if (op == ' !' ) {
49+ qs[i].type = 1 ;
50+ coords.push_back (qs[i].b );
51+ } else {
52+ qs[i].type = 2 ;
53+ coords.push_back (qs[i].a );
54+ coords.push_back (qs[i].b );
55+ }
56+ }
57+ sort (coords.begin (), coords.end ());
58+ coords.erase (unique (coords.begin (), coords.end ()), coords.end ());
59+
60+ auto get_idx = [&](int x) {
61+ return lower_bound (coords.begin (), coords.end (), x) - coords.begin () + 1 ;
62+ };
63+
64+ for (int i = 1 ; i <= n; i++) add (get_idx (cur_p[i]), 1 );
65+
66+ for (int i = 0 ; i < q; i++) {
67+ if (qs[i].type == 1 ) {
68+ add (get_idx (cur_p[qs[i].a ]), -1 );
69+ cur_p[qs[i].a ] = qs[i].b ;
70+ add (get_idx (cur_p[qs[i].a ]), 1 );
71+ } else {
72+ cout << sum (get_idx (qs[i].b )) - sum (get_idx (qs[i].a ) - 1 ) << " \n " ;
73+ }
74+ }
75+ return 0 ;
76+ }
0 commit comments