- Choose the aggregate stored for each interval or prefix.
- Build or initialize the structure from the input.
- Apply updates and combine the affected nodes to answer each query.
Code notes
- 149 lines of C++ from the credited upstream file maximize-count-of-distinct-primes-after-split.cpp.
- The implementation visibly relies on sequence storage, hash lookup, ordered lookup.
- 8 loop blocks detected.
Complexity
Count the build once, then multiply the logarithmic update or query path by the number of operations.
Check the problem constraints before deciding whether this complexity will pass.
Use this to learn the idea, then write your own version.
123 45vector<int> linear_sieve_of_eratosthenes(int n) { 6 vector<int> spf(n + 1, -1);7 vector<int> primes;8 for (int i = 2; i <= n; ++i) {9 if (spf[i] == -1) {10 spf[i] = i;11 primes.emplace_back(i);12 }13 for (const auto& p : primes) {14 if (i * p > n || p > spf[i]) {15 break;16 }17 spf[i * p] = p;18 }19 }20 return spf;21}22 23const int MAX_N = 1e5;24const auto& SPF = linear_sieve_of_eratosthenes(MAX_N);25class Solution {26public:27 vector<int> maximumCount(vector<int>& nums, vector<vector<int>>& queries) {28 unordered_map<int, set<int>> lookup;29 SegmentTree st(size(nums) - 1);30 const auto& add = [&](int i, int d) {31 const auto& x = nums[i];32 if (SPF[x] != x) {33 return;34 }35 if (d == 1) {36 lookup[x].emplace(i);37 }38 if (size(lookup[x]) == 1) {39 st.update(0, size(nums) - 2, d);40 } else if (i == *begin(lookup[x])) {41 st.update(i, *next(begin(lookup[x])) - 1, d);42 } else if (i == *rbegin(lookup[x])) {43 st.update(*next(rbegin(lookup[x])), i - 1, d);44 }45 if (d == -1) {46 lookup[x].erase(i);47 }48 };49 50 for (int i = 0; i < size(nums); ++i) {51 add(i, +1);52 }53 vector<int> result(size(queries));54 for (int i = 0; i < size(queries); ++i) {55 const int idx = queries[i][0], x = queries[i][1];56 if (nums[idx] != x) {57 add(idx, -1);58 nums[idx] = x;59 add(idx, +1);60 }61 result[i] = st.tree[1]; 62 }63 return result;64 }65 66private:67 class SegmentTree {68 public:69 explicit SegmentTree(int N)70 : base_(N > 1 ? 1 << (__lg(N - 1) + 1) : 1),71 lazy_(base_),72 tree(N > 1 ? 1 << (__lg(N - 1) + 2) : 2) {73 74 }75 76 void update(int L, int R, const int val) {77 L += base_;78 R += base_;79 80 81 int L0 = L, R0 = R;82 for (; L <= R; L >>= 1, R >>= 1) {83 if ((L & 1) == 1) {84 apply(L++, val);85 }86 if ((R & 1) == 0) {87 apply(R--, val);88 }89 }90 pull(L0);91 pull(R0);92 }93 94 int query(int L, int R) {95 if (L > R) {96 return 0;97 }98 L += base_;99 R += base_;100 push(L);101 push(R);102 int left = 0, right = 0;103 for (; L <= R; L >>= 1, R >>= 1) {104 if ((L & 1) == 1) {105 left = max(left, tree[L++]);106 }107 if ((R & 1) == 0) {108 right = max(tree[R--], right);109 }110 }111 return max(left, right);112 }113 114 vector<int> tree;115 116 private:117 void apply(int x, const int val) {118 tree[x] += val;119 if (x < base_) {120 lazy_[x] += val;121 }122 }123 124 void pull(int x) {125 while (x > 1) {126 x >>= 1;127 tree[x] = max(tree[x << 1], tree[(x << 1) + 1]);128 if (lazy_[x]) {129 tree[x] += lazy_[x];130 }131 }132 }133 134 void push(int x) {135 for (int h = __lg(x) - 1; h > 0; --h) {136 int y = x >> h;137 if (lazy_[y]) {138 apply(y << 1, lazy_[y]);139 apply((y << 1) + 1, lazy_[y]);140 lazy_[y] = 0;141 }142 }143 }144 145 int base_;146 vector<int> lazy_;147 };148};149