Processing math: 100%
My Algorithm : kopricky アルゴリズムライブラリ

kopricky アルゴリズムライブラリ

Update Interval

コードについての説明

Segment Tree で持てないような大きな範囲についての範囲の 0,1 (ON/OFF) を管理する. 1 (ON) の範囲を set<pair<int, int> > で持つ.
また範囲 [1,3), [3,5) などはちゃんと [1,5) にマージされるように実装している.
たまに使えるシーンがある.

時間計算量: 更新 ならし O(logn)

コード

  1. //セグ木で持てないくらい大きい範囲の(0,1)の区間更新のクエリに答える
  2. template<typename T> class UpdateInterval
  3. {
  4. private:
  5. using ptt = pair<T,T>;
  6. public:
  7. //1の区間をsetで保持
  8. set<ptt> st;
  9. UpdateInterval(){};
  10. //[l,r)をk(0,1)に更新
  11. void update(T l, T r, int k){
  12. T lb = l, rb = r;
  13. while(1){
  14. auto it = st.lower_bound(ptt(l, numeric_limits<T>::min()));
  15. if(it == st.end()){
  16. break;
  17. }
  18. ptt p = *it;
  19. if(p.first > r){
  20. break;
  21. }
  22. st.erase(it);
  23. if(p.second > r){
  24. rb = max(rb, p.second);
  25. if(!k) st.insert(ptt(r, p.second));
  26. break;
  27. }
  28. }
  29. auto it = st.lower_bound(ptt(l, numeric_limits<T>::min()));
  30. if(it != st.begin()){
  31. --it;
  32. ptt p = *it;
  33. if(p.second >= l){
  34. st.erase(it);
  35. if(!k) st.insert(ptt(p.first, l));
  36. lb = min(lb, p.first);
  37. }
  38. if(p.second > r){
  39. if(!k) st.insert(ptt(r, p.second));
  40. rb = max(rb, p.second);
  41. }
  42. }
  43. if(k) st.insert(ptt(lb, rb));
  44. }
  45. };

verify 用の問題

Atcoder : League of Kyoto 提出コード