สมมติว่าเราต้องการโมดูลช่วง นี่คือโมดูลที่ติดตามช่วงของตัวเลข งานของเราคือการออกแบบและใช้งานอินเทอร์เฟซต่อไปนี้อย่างมีประสิทธิภาพ
- addRange (ซ้าย, ขวา) นี่จะเป็นช่วงครึ่งเปิด [ซ้าย, ขวา) ติดตามทุกจำนวนจริงในช่วงเวลานั้น ตอนนี้ การเพิ่มช่วงเวลาที่ทับซ้อนกับตัวเลขที่ติดตามอยู่บางส่วนควรเพิ่มตัวเลขใดๆ ในช่วงที่ยังไม่ได้ติดตาม
- queryRange(ซ้าย ขวา) ค่านี้จะคืนค่าเป็นจริงเมื่อทุกจำนวนจริงในช่วงเวลา [ซ้าย, ขวา) กำลังถูกติดตาม
- removeRange(ซ้าย, ขวา) การดำเนินการนี้จะหยุดติดตามทุกจำนวนจริงที่กำลังถูกติดตามในช่วงเวลา [ซ้าย, ขวา)
เพื่อแก้ปัญหานี้ เราจะทำตามขั้นตอนเหล่านี้ -
- กำหนดหนึ่งแผนที่ m
- กำหนดฟังก์ชัน addRange() ซึ่งจะใช้ซ้าย ขวา
- removeRange(ซ้าย,ขวา)
- ม[ซ้าย] :=ขวา
- มัน :=ตำแหน่งที่ด้านซ้ายมีอยู่ใน m
- ถ้ามันไม่เท่ากับองค์ประกอบแรกของ m และค่าที่สองของค่าก่อนหน้ามันเหมือนกับด้านซ้าย ดังนั้น −
- (ลดลง 1)
- วินาทีนั้น :=ขวา
- ลบด้านซ้ายจาก m
- ถ้าไม่เท่ากับส่วนก่อนหน้าขององค์ประกอบสุดท้ายของ m และตัวแรกของตัวถัดไปเท่ากับด้านขวา −
- วินาที :=วินาทีถัดไป(มัน)
- ลบ next(it) จาก m
- กำหนดฟังก์ชัน queryRange() ซึ่งจะใช้ซ้าย ขวา
- มัน :=ตำแหน่งของส่วนย่อยของ m ที่มีค่าน้อยกว่าด้านซ้ายทั้งหมด
- ถ้า m ว่างเปล่าหรือเหมือนกับองค์ประกอบแรกของ m แล้ว −
- คืนค่าเท็จ
- (ลดลง 1)
- คืนค่า จริง เมื่อวินาทีของมัน>=ถูกต้อง
- กำหนดฟังก์ชัน removeRange() ซึ่งจะใช้ซ้าย ขวา
- ถ้า m ว่างเปล่า ดังนั้น −
- คืนสินค้า
- มัน :=ตำแหน่งของส่วนย่อยของ m ค่าบนทั้งหมดมากกว่าด้านซ้าย
- ถ้ามันไม่เท่ากับองค์ประกอบแรกของ m แล้ว −
- (ลดลง 1)
- กำหนดอาร์เรย์ v
- ในขณะที่ (ไม่เท่ากับองค์ประกอบสุดท้ายของ m และตัวแรก
- ถ้าอย่างแรก <ซ้ายและอันที่สอง> ซ้าย แล้ว −
- อุณหภูมิ :=วินาทีนั้น
- วินาทีนั้น :=ซ้าย
- ถ้า temp> ถูก แล้ว:m[right] :=temp
- มิฉะนั้นเมื่อแรก>=ซ้ายแล้ว −
- ใส่เข้าไปที่ส่วนท้ายของ v
- ถ้าอย่างที่สอง> ใช่ −
- m[right] :=วินาทีนั้น
- (เพิ่มขึ้น 1)
- ถ้าอย่างแรก <ซ้ายและอันที่สอง> ซ้าย แล้ว −
- ลบ v[i] จาก m
ให้เราดูการใช้งานต่อไปนี้เพื่อความเข้าใจที่ดีขึ้น -
ตัวอย่าง
#include <bits/stdc++.h>
using namespace std;
class RangeModule {
public:
map <int, int> m;
RangeModule() {
}
void addRange(int left, int right) {
removeRange(left, right);
m[left] = right;
map <int, int> :: iterator it = m.find(left);
if(it != m.begin() && prev(it)->second == left){
it--;
it->second = right;
m.erase(left);
}
if(it != prev(m.end()) && next(it)->first == right){
it->second = next(it)->second;
m.erase(next(it));
}
}
bool queryRange(int left, int right) {
map <int, int> :: iterator it = m.upper_bound(left);
if(m.empty() || it == m.begin())return false;
it--;
return it->second >= right;
}
void removeRange(int left, int right) {
if(m.empty())return;
map <int, int> :: iterator it = m.lower_bound(left);
if(it != m.begin())it--;
vector <int> v;
while(it != m.end() && it->first < right){
if(it->first < left && it->second > left){
int temp = it->second;
it->second = left;
if(temp > right){
m[right] = temp;
}
}else if(it->first >= left){
v.push_back(it->first);
if(it->second > right){
m[right] = it->second;
}
}
it++;
}
for(int i = 0; i < v.size(); i++){
m.erase(v[i]);
}
}
};
main(){
RangeModule ob;
ob.addRange(10,20);
ob.removeRange(14,16);
cout << (ob.queryRange(10,14)) << endl;
cout << (ob.queryRange(13,15)) << endl;
cout << (ob.queryRange(16,17));
} อินพุต
Add range (10,20) Remove Range (14,16) Check ranges (10,14), (13,15), (16,17)
ผลลัพธ์
1 0 1