Cho \(N\) đoạn thẳng \([l_i, r_i]\) trên trục số. Thực hiện \(Q\) truy vấn: với đoạn \([a, b]\), liệt kê tất cả đoạn trong tập đã cho giao với \([a, b]\).
Hai đoạn giao nhau khi \([l_i, r_i] \cap [a, b] \neq \emptyset\), tức \(\max(l_i, a) \le \min(r_i, b)\).
graph TD
A["Median m = 5\nS1: đoạn tăng theo l\nS2: đoạn giảm theo r"] --> B["Nhóm trái: r < 5"]
A --> C["Nhóm phải: l > 5"]
B --> D["Đệ quy..."]
C --> E["Đệ quy..."]
S1 (tăng theo \(l_i\)): Khi \(b < m\), đoạn truy vấn \([a, b]\) chỉ giao với đoạn có \(l_i \le b\) (vì \(r_i \ge m > b\) không cần xét). Do S1 tăng dần, chỉ cần lấy prefix có \(l_i \le b\)\(\Rightarrow\) binary search.
S2 (giảm theo \(r_i\)): Khi \(a > m\), chỉ cần đoạn có \(r_i \ge a\). Do S2 giảm dần, binary search.
#include<bits/stdc++.h>usingnamespacestd;structIntervalTree{structNode{intmedian;vector<pair<int,int>>S1;// tăng theo lvector<pair<int,int>>S2;// giảm theo rNode*left=nullptr,*right=nullptr;};Node*root;Node*build(vector<pair<int,int>>&intervals){if(intervals.empty())returnnullptr;Node*node=newNode();// Tìm median của l_ivector<int>lvals;for(auto&[l,r]:intervals)lvals.push_back(l);sort(lvals.begin(),lvals.end());node->median=lvals[lvals.size()/2];vector<pair<int,int>>leftSet,rightSet;for(auto&[l,r]:intervals){if(r<node->median)leftSet.push_back({l,r});elseif(l>node->median)rightSet.push_back({l,r});else{node->S1.push_back({l,r});node->S2.push_back({l,r});}}sort(node->S1.begin(),node->S1.end());sort(node->S2.begin(),node->S2.end(),[](auto&a,auto&b){returna.second>b.second;});node->left=build(leftSet);node->right=build(rightSet);returnnode;}IntervalTree(vector<pair<int,int>>&intervals){root=build(intervals);}voidquery(Node*node,inta,intb,vector<pair<int,int>>&result){if(!node)return;if(b<node->median){// Tìm trong S1: l_i <= bfor(auto&seg:node->S1){if(seg.first<=b)result.push_back(seg);elsebreak;}query(node->left,a,b,result);}elseif(a>node->median){// Tìm trong S2: r_i >= afor(auto&seg:node->S2){if(seg.second>=a)result.push_back(seg);elsebreak;}query(node->right,a,b,result);}else{// [a,b] chứa median → tất cả S1, S2 đều giaofor(auto&seg:node->S1)result.push_back(seg);query(node->left,a,b,result);query(node->right,a,b,result);}}};intmain(){intn,q;cin>>n>>q;vector<pair<int,int>>intervals(n);for(inti=0;i<n;i++)cin>>intervals[i].first>>intervals[i].second;IntervalTreetree(intervals);while(q--){inta,b;cin>>a>>b;vector<pair<int,int>>result;tree.query(tree.root,a,b,result);cout<<result.size()<<"\n";for(auto&[l,r]:result)cout<<l<<" "<<r<<"\n";}return0;}