線段樹離散化+區間修改 - POJ 2528 - Mayor's posters
阿新 • • 發佈:2020-10-28
POJ - 2528 - Mayor's posters
這一題的資料範圍為1e7,由於題目資訊並沒有告訴我們最多有多少個不同的端點值,我們即使離散化處理端點也無法確定陣列長度到底能夠降到多少,因此本題只能老老實實開1e7<<2的陣列.
但是本題離散化處理仍是有必要的,離散化處理可以大大降低時間複雜度(陣列越長,update,query的遞迴層數越多)
另外,本題只需要維護一個lazy標記數字即可,沒必要額外開一個tree陣列,最終查詢所有長度為1的區間(即[i,i])對應的不同的lazy值個數即為最終答案.
#include <cstdio> #include <vector> #include <algorithm> #include <set> #include <cstdlib> using namespace std; #define N 10000000+2 #define MAX(a,b) (a>b?a:b) int lazy[N<<2]; set<int> ans_set; void push_down(int left,int right,int root){ if(lazy[root]){ int left_root = root<<1; int right_root = root<<1|1; lazy[left_root] = lazy[root]; lazy[right_root] = lazy[root]; lazy[root] = 0; } } void update(int left,int right,int root,int update_left,int update_right,int new_val){ if(update_left <= left && update_right >= right){ lazy[root] = new_val; }else{ push_down(left,right,root); int mid = (left+right)>>1; int left_root = root<<1; int right_root = root<<1|1; if(update_left <= mid){ update(left,mid,left_root,update_left,update_right,new_val); } if(update_right > mid){ update(mid+1,right,right_root,update_left,update_right,new_val); } } } void query_all(int left,int right,int root){ if(left == right){ if(lazy[root]) ans_set.insert(lazy[root]); return; // 最後只需要看lazy個數 }else{ push_down(left,right,root); int mid = (left+right)>>1; query_all(left,mid,root<<1); query_all(mid+1,right,root<<1|1); } } typedef pair<int,int> pii; int binarySearch(int head,int tail,int val,const vector<int>& vec){ int ans = 0; while(head <= tail){ int mid = (head+tail)>>1; if(vec[mid] > val){ tail = mid - 1; }else if(vec[mid] < val){ head = mid + 1; }else{ ans = mid; break; } } return ans; } int main(){ int t; scanf("%d",&t); while(t--){ int q; int l,r; int maxn = 0; scanf("%d",&q); vector<pii> vec; set<int> st; for(int i = 0; i < q; i++){ scanf("%d%d",&l,&r); vec.push_back(make_pair(l,r)); st.insert(l); st.insert(r); } vector<int> ord; for(set<int> :: iterator it = st.begin(); it != st.end(); it++){ ord.push_back(*it); } int g = ord.size(); for(int i = 0; i < q; i++){ vec[i].first = binarySearch(0,g-1,vec[i].first,ord) + 1; vec[i].second = binarySearch(0,g-1,vec[i].second,ord) + 1; maxn = MAX(maxn,vec[i].second); } for(int i = 0; i < q; i++){ update(1,maxn,1,vec[i].first,vec[i].second,i+1); } query_all(1,maxn,1); printf("%d\n",ans_set.size()); ans_set.clear(); } system("pause"); return 0; }