https://www.luogu.org/problemnew/show/P3919
看到上面鏈接中的題時,我在學會可持久化線段樹的同時,第一次學會了一個非常屌(cai)的STL大法——rope!!!
這是一個非標准的STL工具,一般情況下要支持c++11或更高才能用(上次去參加APIO時人家毛子評測用的是c++14啊喂!)
正題:
它的頭文件是什么:#include<ext/rope> (注:你可以打開devcpp的目錄去翻一翻rope這個頭文件看看它的操作啊!)
除了頭文件以外還需要什么:using namespace __gnu_cxx; (注:正是因為需要使用這種非std的標准命名空間,大部分競賽才無法支持這個工具)
定義方法:rope<變量類型>變量名稱;
或 crope 變量名稱;
其中crope相當於定義成rope<char>,即定義為string類型
它到底是什么:
那得看你想聽哪種解釋了。
人話解釋:超級string
算法解釋:塊狀鏈表(即講鏈表與數組的優勢結合,形成分塊思想)
用途解釋:這本來是一個用於快速操作string的工具,卻一般被定義成int,然后用作可持久化線段樹!
它有哪些操作(重點):
●如果你把rope定義為string:
insert(int pos, string &s, int n) 將字符串s的前n位插入rope的下標pos處,如沒有參數n則將字符串s的所有位都插入rope的下標pos處 (補充地址知識:如果你不想從字符串下標為0(即第一個字符)的地址開始取n位,就將你想開始取的地址代入。如s+1表示從字符串下標為1(即第二個字符)的地址開始取n位。int、char等變量類型的數組都適用這種方法來更改數組操作的起始位置。)
示例代碼:
1 char a[10]; 2 for(int i=0;i<10;i++) a[i]=i+'0'; 3 r.insert(0,a+1,8); 4 for(int i=0;i<10;i++) cout<<r.at(i);
append(string &s,int pos,int n) 把字符串s中從下標pos開始的n個字符連接到rope的結尾,如沒有參數n則把字符串s中下標pos后的所有字符連接到rope的結尾,如沒有參數pos則把整個字符串s連接到rope的結尾(這里已經給你起始位置參數pos了就沒必要用上述的取地址方法了哈)
(insert和append的區別:insert能把字符串插入到rope中間,但append只能把字符串接到結尾)
substr(int pos, int len) 提取rope的從下標pos開始的len個字符
at(int x) 訪問rope的下標為x的元素
erase(int pos, int num) 從rope的下標pos開始刪除num個字符
copy(int pos, int len, string &s) 從rope的下標pos開始的len個字符用字符串s代替,如果pos后的位數不夠就補足
replace(int pos, string &x);//從rope的下標pos開始替換成字符串x,x的長度為從pos開始替換的位數,如果pos后的位數不夠就補足
以上是常用操作,不常用操作這里就不再贅述。
●如果你把rope定義為int(這里只是以int為例):
insert(int pos, int *s, int n) 將int數組(以下的s都是int數組)s的前n位插入rope的下標pos處,如沒有參數n則將數組s的所有位都插入rope的下標pos處
append(int *s,int pos,int n) 把數組s中從下標pos開始的n個數連接到rope的結尾,如沒有參數n則把數組s中下標pos后的所有數連接到rope的結尾,如沒有參數pos則把整個數組s連接到rope的結尾
substr(int pos, int len) 提取rope的從下標pos開始的len個數
at(int x) 訪問rope的下標為x的元素
erase(int pos, int num) 從rope的下標pos開始刪除num個數
copy(int pos, int len, int *s) 從rope的下標pos開始的len個數用數組s代替,如果pos后的位數不夠就補足
replace(int pos, int *x);//從rope的下標pos開始替換成數組x,x的長度為從pos開始替換的位數,如果pos后的位數不夠就補足
示例代碼:
r.append(3); r.append(1); r.append(2); r.append(1); r=r.substr(1,3); for(int i=0;i<r.size();i++) printf("%d ",r.at(i));
它有哪些好處:
時間復雜度:O(n*sqrt(n)),具體原理詳見塊狀鏈表
空間復雜度:O(玄學),此處非常神奇,假如用rope存n個整數,它幾乎只需要sqrt(n)的塊空間加上一些鏈表指針的微小空間(個人猜測)。比如下面切的這道題就大方地開了100w個rope,每個rope都是一個存了100w個數的版本……我真是震驚了這東西真的這么省空間?
示范切題:以最上面那個鏈接中的題為例(可持久化線段樹模板)
未完待續