NOI2005 維護數列 splay

2021-07-29 15:22:24 字數 2490 閱讀 3729

請寫乙個程式,要求維護乙個數列,支援以下6種操作:(請注意,格式欄中的下劃線『 _ 』表示實際輸入檔案中的空格)

1. 插入 insert_posi_tot_c1_c2_…_ctot 在當前數列的第posi個數字後插入tot個數字:c1, c2, …, ctot;若在數列首插入,則posi為0

2. 刪除 delete_posi_tot 從當前數列的第posi個數字開始連續刪除tot個數字

3. 修改 make-same_posi_tot_c 將當前數列的第posi個數字開始的連續tot個數字統一修改為c

4. 翻轉 reverse_posi_tot 取出從當前數列的第posi個數字開始的tot個數字,翻轉後放入原來的位置

5. 求和 get-sum_posi_tot 計算從當前數列開始的第posi個數字開始的tot個數字的和並輸出

6. 求和最大的子列 max-sum 求出當前數列中和最大的一段子列,並輸出最大和

輸入檔案的第1行包含兩個數n和m,n表示初始時數列中數的個數,m表示要進行的運算元目。

第2行包含n個數字,描述初始時的數列。

以下m行,每行一條命令,格式參見問題描述中的**。

對於輸入資料中的get-sum和max-sum操作,向輸出檔案依次列印結果,每個答案(數字)佔一行。

9 8

2 -6 3 5 1 -5 -3 6 3

get-sum 5 4

max-sum

insert 8 3 -5 7 2

delete 12 1

make-same 3 3 2

reverse 3 6

get-sum 5 4

max-sum

-1 10

1 10

你可以認為在任何時刻,數列中至少有1個數。

輸入資料一定是正確的,即指定位置的數在數列中一定存在。

50%的資料中,任何時刻數列中最多含有30 000個數;

100%的資料中,任何時刻數列中最多含有500 000個數。

100%的資料中,任何時刻數列中任何乙個數字均在[-1 000, 1 000]內。

100%的資料中,m ≤20 000,插入的數字總數不超過4 000 000個,輸入檔案大小不超過20mbytes。

維護乙個splay,就是維護的東西有點多

因為他的insert總長度可能很長,但他同時不會太長,所以把delete的點放到乙個棧裡,以後加入的時候使用

需要維護以下東西(陣列與我程式中的陣列相同)

size[x]表示x子樹的大小

da[x]表示x這個位置的真實值

sum[x]表示x子樹的和(為了維護操作5)

以下為了維護操作6

l[x]表示x子樹所代表的區間左邊開始的最大子串行

r[x]表示x子樹所代表的區間右邊開始的最大子串行

d[x]表示x子樹所代表的區間整體的最大子串行

如何轉移自己想

注意細節

#include

#include

#include

#define fo(i,a,b) for(int i=a;i<=b;i++)

#define n 1001000

using

namespace

std;

int t[n][2],fa[n],s[n],tot,root,s1[n],rev[n],lz[n],l[n],r[n],d[n],sum[n],size[n],da[n],n,m;

int lr(int x)

void down(int x,int v)

void dow1(int z)

void dow2(int z)

}void turn(int z)

void xc(int x,int y)

}void update(int x)

void rotate(int x)

void splay(int x,int y)

if(y==0) root=x;

}int kth(int r,int x)

void del(int x)

int main()

fa[n+1]=n+2;t[n+2][0]=n+1;lz[n+2]=n;update(n+2);

fa[n+2]=tot=root=n+3;t[n+3][0]=n+2;lz[n+3]=n;update(n+3);

scanf("\n");

for(;m;m--)

for(;y>0;y=fa[y]) update(y);

scanf("\n");

}if(ch=='d')//----------刪除

if(ch=='k')//----------修改

if(ch=='r')//----------翻轉

if(ch=='g')//----------求和

if(ch=='x')//----------求最大子串行

}}

noi2005維護數列

請寫乙個程式,要求維護乙個數列,支援以下 6 種操作 請注意,格式欄 中的下劃線 表示實際輸入檔案中的空格 操作編號 輸入檔案中的格式 說明1.插入 insert posi tot c1 c2 c tot 在當前數列的第 posi 個數字後插入 tot 個數字 c1,c2,c tot 若在數列首插 ...

NOI2005 維護數列

陳年老題。我就 碼了4k多。主要就是用splay,然後處理區間上的東西 區間反轉就和模板一樣,但是要記得反轉leftmax和rightmax 區間賦值就把那個區間提取出來,然後給子樹根打個same標記,表示下面的全一樣。區間求最大子段和就和線段樹的套路一樣。區間插入就先弄好一顆平衡樹,然後把原平衡樹...

NOI2005 維護數列

傳送門 我還是沒有逃過在這道題上debug好久的命運 我是使用 fhq treap 來做的這道題。寫的時候寫的挺爽的 調的時候真難受。首先我們先來說說咋做吧。前5個操作對於 fhq treap 來說不在話下,只要多打兩個標記就可以了。但是如何求最大子段和?於是乎我們再打三個標記來維護它 霧 然後我們...