//二分求出x对应的离散化的值 intfind(int x){//找到第一个大于等于x的位置 int low = 0, high = nums.size() - 1; while (low < high) { int mid = low + high >> 1; if (nums[mid] >= x) high = mid; else low = mid + 1; } return high + 1;//映射到1, 2, ...n }
intmain(){ cin >> n >> m; for (int i = 0; i < n; ++i) { int x, c; cin >> x >> c; add.push_back({x, c}); nums.push_back(x); } for (int i = 0; i < m; ++i) { int low, high; cin >> low >> high; query.push_back({low, high}); nums.push_back(low); nums.push_back(high); } //1.将所有值排序 并去掉重复元素 sort(nums.begin(), nums.end()); nums.erase(unique(nums.begin(), nums.end()), nums.end());
//2.处理插入操作 for (auto item : add) { int x = find(item.first);//求x值离散化后的结果坐标 a[x] += item.second; }
//3.预处理前缀和 for (int i = 1; i <= nums.size(); ++i) prefix[i] = prefix[i - 1] + a[i];
//4.处理询问操作 for (auto item : query) { int low = find(item.first), high = find(item.second); cout << prefix[high] - prefix[low - 1] << endl; } return0; }
3.Unique函数实现:
该数字是第一个数字
该数字满足a[i] != a[i - 1];
双指针算法实现
1 2 3 4 5 6
//关于unique函数的实现 vector<int>::iterator unique(vector<int> &a){ int j = 0; for (int i = 0; i < a.size(); ++i) if (!i || a[i] != a[i - 1]) a[j++] = a[i];//a[0] ~ a[j + 1] a中所有满足性质的数字 return a.begin() + j; }
3.区间合并模板
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
//将所有存在交集的区间进行合并 voidmerge(vector<PAIR> &segs){ vector<PAIR> res; //1.将区间按照左端点进行排序 sort(segs.begin(), segs.end()); //2.根据3种不同情况对区间进行合并操作 int st = -2e9, ed = -2e9; for (auto seg : segs) { if (ed < seg.first) {//情况3:两个区间没有任何交集 if (st != -2e9) res.push_back({st, ed}); st = seg.first, ed = seg.second; } else ed = max(ed, seg.second);//情况2:两个区间之间有交集 } if (st != -2e9) res.push_back({st, ed});//将最后的区间加入到结果中(if条件防止输入区间为空) segs = res; }
voidmerge(vector<PAIR> &segs){ vector<PAIR> res; //1.将区间按照左端点进行排序 sort(segs.begin(), segs.end()); //2.根据3种不同情况对区间进行合并操作 int st = -2e9, ed = -2e9; for (auto seg : segs) { if (ed < seg.first) {//情况3:两个区间没有任何交集 if (st != -2e9) res.push_back({st, ed}); st = seg.first, ed = seg.second; } else ed = max(ed, seg.second);//情况2:两个区间之间有交集 } if (st != -2e9) res.push_back({st, ed});//将最后的区间加入到结果中(if条件防止输入区间为空) segs = res; }
intmain(){ cin >> n; for (int i = 0; i < n; ++i) { int low, high; cin >> low >> high; segs.push_back({low, high}); } merge(segs); cout << segs.size() << endl; return0; }