- 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
- 138 lines of C++ from the credited upstream file sum-of-beautiful-subsequences.cpp.
- The implementation visibly relies on sequence storage, hash lookup.
- 17 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.
1234 56const int MOD = 1e9 + 7;7 8class BIT {9public:10 BIT(int n) : bit_(n + 1) { 11 }12 13 void add(int i, int val) {14 ++i;15 for (; i < size(bit_); i += lower_bit(i)) {16 bit_[i] = (bit_[i] + val) % MOD;17 }18 }19 20 int query(int i) const {21 ++i;22 int total = 0;23 for (; i > 0; i -= lower_bit(i)) {24 total = (total + bit_[i]) % MOD;25 }26 return total;27 }28 29private:30 inline int lower_bit(int i) const {31 return i & -i;32 }33 34 vector<int> bit_;35};36 37const auto& factors = [](int n) { 38 vector<vector<int>> result(n + 1);39 for (int i = 1; i <= n; ++i) {40 for (int j = i; j <= n; j += i) {41 result[j].emplace_back(i);42 }43 }44 return result;45};46 47const auto& phi_sieve = [](int n) { 48 vector<int> phi(n + 1);49 iota(begin(phi), end(phi), 0);50 for (int i = 2; i <= n; ++i) {51 if (phi[i] != i) {52 continue;53 }54 for (int j = i; j <= n; j += i) {55 phi[j] -= phi[j] / i;56 }57 }58 return phi;59};60 61const int MAX_NUM = 7 * 1e4;62const auto& FACTORS = factors(MAX_NUM);63const auto& PHI = phi_sieve(MAX_NUM);64class Solution {65public:66 int totalBeauty(vector<int>& nums) {67 const auto& mx = ranges::max(nums);68 vector<int> val_to_idx(mx + 1);69 const auto& count = [&](const auto& arr){70 vector<int> sorted_arr(arr);71 sort(begin(sorted_arr), end(sorted_arr));72 for (int i = 0; i < size(sorted_arr); ++i) { 73 val_to_idx[sorted_arr[i]] = i;74 }75 BIT bit(size(arr));76 for (const auto& x : arr) {77 bit.add(val_to_idx[x], bit.query(val_to_idx[x] - 1) + 1);78 }79 return bit.query(size(arr) - 1);80 };81 82 vector<vector<int>> lookup(ranges::max(nums) + 1);83 for (const auto& x : nums) {84 for (const auto& d : FACTORS[x]) {85 lookup[d].emplace_back(x);86 }87 }88 int result = 0;89 vector<int> cnt(mx + 1);90 for (int64_t g = size(cnt) - 1; g >= 1; --g) {91 result = (result + (static_cast<int64_t>(PHI[g]) * count(lookup[g])) % MOD) % MOD;92 }93 return result;94 }95};96 979899100101class Solution2 {102public:103 int totalBeauty(vector<int>& nums) {104 const auto& count = [&](const auto& arr){105 unordered_set<int> arr_set(cbegin(arr), cend(arr));106 vector<int> sorted_arr(cbegin(arr_set), cend(arr_set));107 sort(begin(sorted_arr), end(sorted_arr));108 unordered_map<int, int> val_to_idx;109 for (int i = 0; i < size(sorted_arr); ++i) { 110 val_to_idx[sorted_arr[i]] = i;111 }112 BIT bit(size(val_to_idx));113 for (const auto& x : arr) {114 bit.add(val_to_idx[x], bit.query(val_to_idx[x] - 1) + 1);115 }116 return bit.query(size(val_to_idx) - 1);117 };118 119 const auto& mx = ranges::max(nums);120 vector<vector<int>> lookup(ranges::max(nums) + 1);121 for (const auto& x : nums) {122 for (const auto& d : FACTORS[x]) {123 lookup[d].emplace_back(x);124 }125 }126 int result = 0;127 vector<int> cnt(mx + 1);128 for (int64_t g = size(cnt) - 1; g >= 1; --g) {129 cnt[g] = count(lookup[g]);130 for(int ng = g + g; ng <= mx; ng += g){131 cnt[g] = ((cnt[g] - cnt[ng]) % MOD + MOD) % MOD;132 }133 result = (result + (g * cnt[g]) % MOD) % MOD;134 }135 return result;136 }137};138