日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

【可持久化线段树?!】rope史上最全详解

發(fā)布時(shí)間:2024/10/12 编程问答 66 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【可持久化线段树?!】rope史上最全详解 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

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)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。