維修數列 NOI2005

2022-05-27 11:21:18 字數 1732 閱讀 9373

好久沒寫題解了 來水一篇題解

請寫乙個程式,要求維護乙個數列,支援以下 6 種操作:

輸入的第1行包含兩個數 \(n\) 和 \(m(m \leq 20 000)\),\(n\) 表示初始時數列中數的個數,\(m\) 表示要進行的運算元目。

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

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

任何時刻數列中最多含有 \(500000\) 個數,數列中任何乙個數字均在 \([-1 000, 1 000]\) 內。

插入的數字總數不超過 \(4 000 000\) 個,輸入檔案大小不超過20mb。

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

一道平衡樹維護各種標記以及pushup,pushdown的模板題?

我這裡用的是飛旋非旋treap,splay也可以做,但是顯然非旋treap要比較好寫

維護最大子段和的套路就是維護區間最大字首和以及最大字尾和,pushup時:

最大字首和 = max(左兒子最大字首和,左兒子區間和+當前節點權值+右兒子最大字首和)

最大字尾和 = max(右兒子最大字尾和,右兒子區間和+當前節點權值+左兒子最大字尾和)

最大子段和 = max( max(左兒子最大子段和,右兒子最大子段和),左兒子最大字尾和+當前節點權值+右兒子最大字首和)

此題細節特別多:

#include #define n 500005

#define m 4000005

using namespace std;

templateinline void read(t &num)

int n, m, nowtot;

int rt, tot, siz[m], val[m], rnd[m], ch[m][2], tag[m], rev[m];

int mx[m], sum[m], lmx[m], rmx[m];

const int inf = 0x7fffffff;

inline int newnode(int v)

inline void pushup(int x)

inline void change(int x, int v)

inline void rev(int x)

inline void pushdown(int x)

if (rev[x])

}void split(int now, int k, int &x, int &y)

pushdown(now);

if (k > siz[ch[now][0]]) else

pushup(now);

}int merge(int x, int y) else

}char s[50];

int main()

nowtot = n;

for (int i = 1; i <= m; i++)

rt = merge(x, y);

} else if (s[0] == 'd') else if (s[0] == 'r') else if (s[0] == 'g') else if (s[2] == 'k') else

} return 0;

}

NOI 2005 維修數列

noi 2005 維修數列 典型的伸展樹模板題 參考 include include include include include using namespace std define key value ch ch root 1 0 const int maxn 500010 const int...

NOI2005 維修數列

輸入的第1 行包含兩個數n 和m m 20 000 n 表示初始時數列中數的個數,m表示要進行的運算元目。第2行包含n個數字,描述初始時的數列。以下m行,每行一條命令,格式參見問題描述中的 任何時刻數列中最多含有500 000個數,數列中任何乙個數字均在 1 000,1 000 內。插入的數字總數不...

noi2005維護數列

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