离散化模型
离散化算法常用来解决负值问题和取值范围过大问题。
模板:
使用lower_bound或者库函数set,map来写
写法1.lower_bound速度快
// 把要进行离散化的值排序去重后放入alls数组中,用二分进行映射。
int find(int x) { return lower_bound(alls.begin(), alls.end(),x) - alls.begin() + 1; }
set<int> st; unordered_map<int, int> mp;
// 使用set来进行排序去重 vector<int> alls(st.begin(), st.end()); for(int i = 0; i < alls.size(); i ++ ) mp[alls[i]] = i + 1;
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<vector> #include<set> #include<unordered_map> using namespace std; typedef pair<int, int> PII; const int N = 3e5 + 10; int n, m; set<int> st; unordered_map<int, int> mp; vector<PII> add, q; int a[N], s[N]; int main() { cin >> n >> m; for(int i = 0; i < n; i ++ ) { int x, c; cin >> x >> c; st.insert(x); add.push_back({x, c}); } for(int i = 0; i < m; i ++ ) { int l, r; cin >> l >> r; st.insert(l); st.insert(r); q.push_back({l, r}); } vector<int> alls(st.begin(), st.end()); for(int i = 0; i < alls.size(); i ++ ) mp[alls[i]] = i + 1; for(auto &i : add) { int pos = mp[i.first]; a[pos] += i.second; } for(int i = 1; i <= alls.size(); i ++ ) { s[i] = s[i - 1] + a[i]; } for(auto &i : q) { int l = mp[i.first], r = mp[i.second]; cout << s[r] - s[l - 1] << endl; } return 0; }
树状数组 + 离散化
class Solution { public: int n; vector<int> tr = vector<int>(100005, 0); int lowbit(int x) { return x & -x; } void update(int x) { for(int i = x; i <= n; i += lowbit(i)) { tr[i] += 1; } } int query(int u) { int res = 0; for(int i = u; i > 0; i -= lowbit(i)) { res += tr[i]; } return res; } vector<int> countSmaller(vector<int>& nums) { n = nums.size(); vector<int> res(n, 0); if(n == 0) return {}; set<int> st; for(auto num: nums) st.insert(num); unordered_map<int, int> mp; int idx = 1; for(auto it: st) mp[it] = idx ++ ; for(int i = n - 1; i >= 0; i -- ) { res[i] = query(mp[nums[i]]); update(mp[nums[i]] + 1); } return res; } };