【可持久化线段树?!】rope史上最全详解
https://www.luogu.org/problemnew/show/P3919
看到上面鏈接中的題時(shí),我在學(xué)會(huì)可持久化線段樹(shù)的同時(shí),第一次學(xué)會(huì)了一個(gè)非常屌(cai)的STL大法——rope!!!
這是一個(gè)非標(biāo)準(zhǔn)的STL工具,一般情況下要支持c++11或更高才能用(上次去參加APIO時(shí)人家毛子評(píng)測(cè)用的是c++14啊喂!)
?
正題:
它的頭文件是什么:#include<ext/rope> (注:你可以打開(kāi)devcpp的目錄去翻一翻rope這個(gè)頭文件看看它的操作啊!)
?
除了頭文件以外還需要什么:using namespace __gnu_cxx; (注:正是因?yàn)樾枰褂眠@種非std的標(biāo)準(zhǔn)命名空間,大部分競(jìng)賽才無(wú)法支持這個(gè)工具)
?
定義方法:rope<變量類型>變量名稱;
或 ? ? ? crope 變量名稱;
其中crope相當(dāng)于定義成rope<char>,即定義為string類型
?
它到底是什么:
那得看你想聽(tīng)哪種解釋了。
人話解釋:超級(jí)string
算法解釋:塊狀鏈表(即講鏈表與數(shù)組的優(yōu)勢(shì)結(jié)合,形成分塊思想)
用途解釋:這本來(lái)是一個(gè)用于快速操作string的工具,卻一般被定義成int,然后用作可持久化線段樹(shù)!
?
它有哪些操作(重點(diǎn)):
●如果你把rope定義為string:
insert(int pos, string &s, int n) 將字符串s的前n位插入rope的下標(biāo)pos處,如沒(méi)有參數(shù)n則將字符串s的所有位都插入rope的下標(biāo)pos處?(補(bǔ)充地址知識(shí):如果你不想從字符串下標(biāo)為0(即第一個(gè)字符)的地址開(kāi)始取n位,就將你想開(kāi)始取的地址代入。如s+1表示從字符串下標(biāo)為1(即第二個(gè)字符)的地址開(kāi)始取n位。int、char等變量類型的數(shù)組都適用這種方法來(lái)更改數(shù)組操作的起始位置。)
示例代碼:
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中從下標(biāo)pos開(kāi)始的n個(gè)字符連接到rope的結(jié)尾,如沒(méi)有參數(shù)n則把字符串s中下標(biāo)pos后的所有字符連接到rope的結(jié)尾,如沒(méi)有參數(shù)pos則把整個(gè)字符串s連接到rope的結(jié)尾(這里已經(jīng)給你起始位置參數(shù)pos了就沒(méi)必要用上述的取地址方法了哈)
(insert和append的區(qū)別:insert能把字符串插入到rope中間,但append只能把字符串接到結(jié)尾)
?
substr(int pos, int len) 提取rope的從下標(biāo)pos開(kāi)始的len個(gè)字符
?
?at(int x) 訪問(wèn)rope的下標(biāo)為x的元素
erase(int pos, int num) 從rope的下標(biāo)pos開(kāi)始刪除num個(gè)字符
?
copy(int pos, int len, string &s) 從rope的下標(biāo)pos開(kāi)始的len個(gè)字符用字符串s代替,如果pos后的位數(shù)不夠就補(bǔ)足
?
?replace(int pos, string &x);//從rope的下標(biāo)pos開(kāi)始替換成字符串x,x的長(zhǎng)度為從pos開(kāi)始替換的位數(shù),如果pos后的位數(shù)不夠就補(bǔ)足
?
以上是常用操作,不常用操作這里就不再贅述。
?
? ●如果你把rope定義為int(這里只是以int為例):
?insert(int pos, int *s, int n) 將int數(shù)組(以下的s都是int數(shù)組)s的前n位插入rope的下標(biāo)pos處,如沒(méi)有參數(shù)n則將數(shù)組s的所有位都插入rope的下標(biāo)pos處
?
append(int *s,int pos,int n)?把數(shù)組s中從下標(biāo)pos開(kāi)始的n個(gè)數(shù)連接到rope的結(jié)尾,如沒(méi)有參數(shù)n則把數(shù)組s中下標(biāo)pos后的所有數(shù)連接到rope的結(jié)尾,如沒(méi)有參數(shù)pos則把整個(gè)數(shù)組s連接到rope的結(jié)尾
?
?substr(int pos, int len) 提取rope的從下標(biāo)pos開(kāi)始的len個(gè)數(shù)
?
at(int x) 訪問(wèn)rope的下標(biāo)為x的元素
erase(int pos, int num) 從rope的下標(biāo)pos開(kāi)始刪除num個(gè)數(shù)
?
copy(int pos, int len, int *s) 從rope的下標(biāo)pos開(kāi)始的len個(gè)數(shù)用數(shù)組s代替,如果pos后的位數(shù)不夠就補(bǔ)足
?
? replace(int pos, int *x);//從rope的下標(biāo)pos開(kāi)始替換成數(shù)組x,x的長(zhǎng)度為從pos開(kāi)始替換的位數(shù),如果pos后的位數(shù)不夠就補(bǔ)足
示例代碼:
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));?
?
它有哪些好處:
時(shí)間復(fù)雜度:O(n*sqrt(n)),具體原理詳見(jiàn)塊狀鏈表
空間復(fù)雜度:O(玄學(xué)),此處非常神奇,假如用rope存n個(gè)整數(shù),它幾乎只需要sqrt(n)的塊空間加上一些鏈表指針的微小空間(個(gè)人猜測(cè))。比如下面切的這道題就大方地開(kāi)了100w個(gè)rope,每個(gè)rope都是一個(gè)存了100w個(gè)數(shù)的版本……我真是震驚了這東西真的這么省空間?
?
示范切題:以最上面那個(gè)鏈接中的題為例(可持久化線段樹(shù)模板)
未完待續(xù)
?
轉(zhuǎn)載于:https://www.cnblogs.com/scx2015noip-as-php/p/rope.html
總結(jié)
以上是生活随笔為你收集整理的【可持久化线段树?!】rope史上最全详解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 退市的股票有重新上市的吗
- 下一篇: art-template-loader: