請寫乙個程式,要求維護乙個數列,支援以下 6 種操作:(請注意,格式欄 中的下劃線『 _ 』表示實際輸入檔案中的空格)
操作編號
輸入檔案中的格式
說明1. 插入
insert_posi_tot_c1_c2_..._c
tot
在當前數列的第 posi 個數字後插入 tot
個數字:c1, c2, …, c
tot;若在數列首插
入,則 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
-1101【樣例說明】10
初始時,我們擁有數列 2 -6 3 5 1 -5 -3 6 3
執行操作 get-sum 5 4,表示求出數列中從第 5 個數開始連續 4 個數字之和,1+(-5)+(-3)+6 = -1:
2 -6 3 5 1 -5 -3 6 3執行操作 max-sum,表示要求求出當前數列中最大的一段和,應為 3+5+1+(-5)+(-3)+6+3 = 10:
2 -6 3 5 1 -5 -3 6 3執行操作 insert 8 3 -5 7 2,即在數列中第 8 個數字後插入-5 7 2,
2 -6 3 5 1 -5 -3 6 -5 7 2 3執行操作 delete 12 1,表示刪除第 12 個數字,即最後乙個:
2 -6 3 5 1 -5 -3 6 -5 7 2執行操作 make-same 3 3 2,表示從第 3 個數開始的 3 個數字,統一修改為 2:
2 -6 3 5 1 -5 -3 6 -5 7 2改為
2 -6 2 2 2 -5 -3 6 -5 7 2執行操作 reverse 3 6,表示取出數列中從第 3 個數開始的連續 6 個數:
2 -6 2 2 2 -5 -3 6 -5 7 2如上所示的灰色部分 2 2 2 -5 -3 6,翻轉後得到 6 -3 -5 2 2 2,並放回原來位置:
2 -6 6 -3 -5 2 2 2 -5 7 2最後執行 get-sum 5 4 和 max-sum,不難得到答案 1 和 10。
2 -6 6 -3 -5 2 2 2 -5 7 2【評分方法】
本題設有部分分,對於每乙個測試點:
請注意:如果你的程式只能正確處理某一種操作,請確定在輸出檔案正確的位置上列印結果,即必須為另一種操作留下對應的行,否則我們不保證可以正確評分。
【資料規模和約定】
splay維護數列模板題,我們認為該splay的中序遍歷即為原數列,那麼處理區間只需將該區間左邊界點左相鄰點旋轉至樹根,將區間右邊界點右相鄰點旋轉至樹根右兒子,則樹根右兒子的左兒子的子樹即為所要處理的區間,
**:
#include #include #include #include #include #include using namespace std;string s;
const int maxn=500000+10;
queueq;
const int inf=0x7fffffff;
int tr[maxn][3];
int root;
int rotated[maxn]=;
long long summ[maxn]=;
long long maxx[maxn]=;
int fa[maxn];
int n;
int id[maxn];
int a[maxn];
int v[maxn];
long long lmax[maxn];
long long rmax[maxn];
int size[maxn];
int cnt;
int tag[maxn];
inline void pushup(int x)
inline void pushdown(int x)
else
} if(rotated[x])
}inline void rotate(int x,int& o)
inline void splay(int x,int& k)
rotate(x,k); }}
inline int find(int o,int k)
inline void dec(int x)
inline int spilt(int o,int tot)
inline void sum(int o,int k)
inline void modify(int k,int tot,int val)
inline void rev(int o,int k)
}inline void del(int o,int k)
inline void build(int l,int r,int f)
else
v[now]=a[mid];
fa[now]=last;
pushup(now);
tr[last][mid>=f]=now;
}inline void insert(int k,int tot)
inline void dfs(int x)
int main()
if(s[0]=='r')
rev(k,tot);
if(s[0]=='g')
sum(k,tot);
//dfs(root);
//printf("\n");
}return 0;
}
NOI2005 維護數列
陳年老題。我就 碼了4k多。主要就是用splay,然後處理區間上的東西 區間反轉就和模板一樣,但是要記得反轉leftmax和rightmax 區間賦值就把那個區間提取出來,然後給子樹根打個same標記,表示下面的全一樣。區間求最大子段和就和線段樹的套路一樣。區間插入就先弄好一顆平衡樹,然後把原平衡樹...
NOI2005 維護數列
傳送門 我還是沒有逃過在這道題上debug好久的命運 我是使用 fhq treap 來做的這道題。寫的時候寫的挺爽的 調的時候真難受。首先我們先來說說咋做吧。前5個操作對於 fhq treap 來說不在話下,只要多打兩個標記就可以了。但是如何求最大子段和?於是乎我們再打三個標記來維護它 霧 然後我們...
NOI2005 維護數列
嘟嘟嘟 這題我寫的時候還是挺順的,邊寫邊想為啥學姐說我是 勇士 然後我用了大半天的debug時間理解了這句話 先不說那幾個把人坑到退役的點,光說這幾個操作,其實都聽基礎的。我感覺唯一要說一下的就是插入一串數 我們先把這些數建成乙個splay,然後把這個splay的根節點連到對應的點的兒子節點即可。然...