<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      pbds tree 使用擴展——2025.7.7 鮮花

      pbds tree 使用擴展

      白鳥過河灘
      風把我不想知道的事情
      告訴我
      河把我不想忘記的故事
      也帶走
      我摘下我的翅膀
      它變成白鳥
      白鳥我的白鳥 逆著風去吧
      飛過河灘 揮一揮 一去不回還
      一去不回還 風起水起難靠岸
      白鳥白鳥不要回頭望
      你要替我飛去那地方
      一去那地方 那是你我共同故鄉
      抓住和抓不住的照片 哪張更美
      去過和沒去過的地方 哪里更遠
      白鳥我的白鳥
      你要飛得更高不要回來
      若還想與我相見
      就來我的夢里邊
      白鳥過河灘
      揮一揮 一去不回還
      一去不回還 風起水起難靠岸
      白鳥白鳥不要回頭望
      你要替我飛去那地方
      一去那地方 那是你我共同故鄉
      別回來 我將終究順流入大海
      順流入大海
      海不問我從何處來
      長風長風飄在山海間
      白鳥白鳥展翅入蒼天
      一去入蒼天 蒼天遠在海背面
      一去入蒼天 蒼天遠比海更遠
      

      震驚,treesplitjoin 竟然是 \(\mathcal{O}(n)\)

      標題黨一下,但我測出來就是這樣的,詳見 這個討論,有沒有人能回答一下 QwQ。

      前兩天閑的沒事整的。

      看一下其定義:

      __gnu_pbds::tree<Key, Mapped, Cmp_Fn = std::less<Key>, Tag = rb_tree_tag,
                       Node_Update = null_tree_node_update,
                       Allocator = std::allocator<char>>
      

      Key 是值的類型,Mapped 是映射到的值的類型,類似 map 的第二個參數,沒有可以寫 null_typeTag 是平衡樹類型,正常人不會用其他的,Node_Update 是節點合并方式,等下講,Allocator 是內存池。

      Node_Update 內置的有兩個,一個是 null_tree_node_update 表示啥都不干,另一個是 tree_order_statistics_node_update 表示維護子樹大小,支持 order_of_key(x)find_by_order(x) 方法。

      我們想盡可能的自定義這個,就白嫖一個紅黑樹和內存管理的板子。

      于是我們自定義 Node_Update

      大致結構如下:

      template <class cIt, class It, class Cmp, class _A> struct Up{
      	typedef int metadata_type;
      	virtual cIt node_begin() const = 0;
      	virtual cIt node_end() const = 0;
      	void operator()(It t, cIt end){}
      };
      

      這里的 metadata_type 是維護的附加信息的類型,像是什么都行,這里暫時先用 int 代替。

      cItconst 類型封裝指針,It 是封裝指針,Cmp 是比較方法,_A 是內存池。

      pbds 的 tree 的指針封了很多層,這里簡單說一下:

      一般用 lower_bound 之類的方法得到的是值指針,其解引用為節點的值。

      這里傳入的 cItIt 的指針是封裝指針,其把節點指針封裝了一下。

      節點指針是指向平衡樹上一個節點的指針,我們可以用 .m_p_nd 獲得一個值指針或一個封裝指針的節點指針。節點指針有如下幾個比較常用的成員:

      m_p_left 其左二子的指針,m_p_right 其右兒子的指針,m_p_parent 其父親指針,m_metadata 其附加信息的值,其解引用為節點的值。

      注意 m_metadata 要修改要強轉成 metadata_type&

      封裝指針既然是其封裝,則一定有一些函數來調用:.get_l_child() 獲得左兒子,.get_r_child() 獲得右兒子,.get_metadata() 獲得附加值,其解引用為節點的值。注意到其沒有封裝父指針。

      我們拋棄這些封裝,直接用節點指針即可。

      函數 node_begin() 返回根節點的封裝指針,node_end() 返回空節點(即葉子節點的兒子)的封裝指針。

      operator() 是合并方式,將 t 的左右節點合并,endnode_end() 是一樣的,可以直接不管。

      于是給出如下宏定義:

      #define Fm(t) ((t).m_p_nd)
      #define lson (Fm(t)->m_p_left)
      #define rson (Fm(t)->m_p_right)
      #define Dt(t) ((t) == node_end() ? 0 : Fm(t)->m_metadata)
      #define Cg(t) (int&)(Fm(t)->m_metadata)
      

      Fm 表示獲得其節點指針,lsonrson 是其左右兒子,Dt 是獲得值,Cg是修改值。

      還可以在 Up 中寫些函數,最后會是 tree 的成員函數,類似 order_of_key(x)find_by_order(x)

      我們寫一個節點類:

      struct Nd{ int v; mutable int c; bool operator<(const Nd &_) const { return v < _.v; } };
      

      為了方便以后搞事,我們直接將 tree 繼承下來:

      struct Rbt : private __gnu_pbds::tree<Nd, __gnu_pbds::null_type, less<Nd>, __gnu_pbds::rb_tree_tag, Up>{}
      

      然后我們可以在里面改 inserterase 之類的。

      update_to_top(Fm(t), (node_update*)this) 可以直接 updata 到頂。

      pushdown 就要自己在 Up 里寫一個了。

      于是我們基本能實現平衡樹所有功能了(除了分裂合并)。

      這里給一個 P6136 【模板】普通平衡樹(數據加強版) 的代碼:

      Code
      /*
      ulimit -s 128000 && clear && g++ % -o %< -O2 -std=c++14 -DLOCAL -Wall -Wextra && time ./%< && size %<
      ulimit -s 128000 && clear && g++ % -o %< -O2 -std=c++14 -DLOCAL -Wall -Wextra -fsanitize=address,undefined -g && time ./%< && size %<
      echo && cat out.out && echo
      */
      #include <bits/stdc++.h>
      #include <bits/extc++.h>
      using namespace std;
      using llt = long long;
      using llf = long double;
      using ull = unsigned long long;
      #define endl '\n'
      #ifdef LOCAL
      FILE *InFile = freopen("in.in", "r", stdin), *OutFile = freopen("out.out", "w", stdout);
      #endif
      
      struct Nd{ int v; mutable int c; bool operator<(const Nd &_) const { return v < _.v; } };
      #define Fm(t) ((t).m_p_nd)
      template <class cIt, class It, class Cmp, class _A> struct Up{
      	typedef int metadata_type;
      #define lson (Fm(t)->m_p_left)
      #define rson (Fm(t)->m_p_right)
      #define Dt(t) ((t) == node_end() ? 0 : Fm(t)->m_metadata)
      #define Cg(t) (int&)(Fm(t)->m_metadata)
      	virtual cIt node_begin() const = 0;
      	virtual cIt node_end() const = 0;
      	void operator()(It t, cIt end){
      		It ls = lson, rs = rson;
      		int s = 0;
      		if(ls != end) s += Dt(ls);
      		if(rs != end) s += Dt(rs);
      		Cg(t) = s + (*t)->c;
      	}
      	int kth(int k){
      		cIt t = node_begin(), _ = node_end();
      		while(t != _){
      			cIt ls = lson, rs = rson; int s = Dt(ls);
      			if(k <= s) t = ls;
      			else if(k <= s + (*t)->c) return (*t)->v;
      			else k -= s + (*t)->c, t = rs;
      		}
      		return -1;
      	}
      	int rnk(int v){
      		cIt t = node_begin(), _ = node_end(); int r = 1;
      		while(t != _){
      			cIt ls = lson, rs = rson;
      			if(v <= (*t)->v) t = ls;
      			else r += (*t)->c + Dt(ls), t = rs;
      		}
      		return r;
      	}
      #undef lson
      #undef rson
      #undef Dt
      #undef Cg
      };
      struct Rbt : private __gnu_pbds::tree<Nd, __gnu_pbds::null_type, less<Nd>, __gnu_pbds::rb_tree_tag, Up>{
      #define Upd(t) update_to_top(Fm(t), (node_update*)this)
      	void Ins(int v){
      		auto k = lower_bound({v, 0});
      		if(k != end() && k->v == v) ++k->c, Upd(k);
      		else insert({v, 1});
      	}
      	void Era(int v){
      		auto k = lower_bound({v, 0});
      		if(k != end() && k->c > 1) --k->c, Upd(k);
      		else erase(k);
      	}
      	int Rnk(int v){ return rnk(v); }
      	int Kth(int k){ return kth(k); }
      	int Pre(int v){ return (--lower_bound({v, 0}))->v; }
      	int Nxt(int v){ return (upper_bound({v, 0}))->v; }
      #undef Upd
      } rbt;
      #undef Fm
       
      int n, m, lans, aas;
      int main(){
      	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
      	cin >> n >> m;
      	for(int i = 1, v; i <= n; ++i) cin >> v, rbt.Ins(v);
      	for(int i = 1; i <= m; ++i){
      		int op, v; cin >> op >> v, v ^= lans;
      		if(op == 1) rbt.Ins(v);
      		else if(op == 2) rbt.Era(v);
      		else if(op == 3) aas ^= lans = rbt.Rnk(v);
      		else if(op == 4) aas ^= lans = rbt.Kth(v);
      		else if(op == 5) aas ^= lans = rbt.Pre(v);
      		else aas ^= lans = rbt.Nxt(v);
      	}
      	cout << aas;
      }
      
      P





      posted @ 2025-07-07 19:01  xrlong  閱讀(92)  評論(0)    收藏  舉報

      Loading

      主站蜘蛛池模板: 亚洲精品美女一区二区| 成人看的污污超级黄网站免费| 久久精品国产99久久久古代| 无码中文字幕av免费放| 亚洲综合国产精品第一页| 国产在线无码不卡播放| 午夜福利国产盗摄久久性| 色吊a中文字幕一二三区| 久久久久人妻一区二区三区| 少妇精品视频一码二码三| 久久精品熟女亚洲av艳妇| 精品国产av无码一区二区三区| 日韩精品中文字幕有码| 国产乱xxxxx97国语对白| 亚洲熟女一区二区av| 亚洲AV永久无码精品秋霞电影影院| 深夜精品免费在线观看| 亚洲精品97久久中文字幕无码| 欧美色欧美亚洲高清在线视频 | 亚洲码和欧洲码一二三四| 美女黄18以下禁止观看| 砀山县| 亚洲日韩AV秘 无码一区二区| 人妻精品动漫H无码中字| 洛隆县| 久久精品国产99久久美女| 国产精品高清国产三级囯产AV| 国产成人精品2021欧美日韩| 白嫩少妇无套内谢视频| 国产成a人亚洲精v品无码性色| 91老熟女老人国产老太| 亚洲夂夂婷婷色拍WW47| 亚洲一区久久蜜臀av| 农村妇女野外一区二区视频| 狂野欧美性猛交免费视频| 国产人妻大战黑人20p| 国产在线观看免费人成视频| 国产午夜精品理论大片| av综合亚洲一区二区| 亚洲成精品动漫久久精久| 欧美三级欧美成人高清|