「你動規無力,圖論不穩,資料結構鬆散,貪心遲鈍,沒一樣像樣的,就你還想和我同台競技,做你的美夢!今天這場比賽,就是要讓你知道你是多麼
的無能!!」
不訓練,無以為戰。有
n 項能力是acm
競賽要求的,訓練則能提公升,忽略則會荒廢。這m
天,你能做到如何。
第一行兩個整數
n ,
m ,分別表示有
n 項能力要求,共有
m 天。
第二行n
個整數,第
i 個整數ai
表示第i 項能力的數值。
接下來m
行,每行開始先讀入乙個整數si
,表明這是一次詢問還是一次能力變化。si
=0,表明這是一次詢問,然後讀入兩個整數li
,ri ,表示詢問在[l
i,ri
] 區間中任選一段連續序列,這段序列中所有能力值之和最大能是多少。si
=1,表明這是一次能力變化,然後讀入兩個整數xi
,wi ,表示第xi
項能力變為了wi
。1≤n,m≤
100000,−
10000≤a
i≤10000,1
≤li≤
ri≤n
,1≤x
i≤n,
−10000≤w
i≤10000
有多少詢問就輸出多少行,每行輸出乙個整數,作為對該詢問的回答。
sample input
sample output
4 41 2 3 4
0 1 3
1 3 -3
0 2 4
0 3 3
64-3
此題使用線段樹解決。不過與一般的線段樹不同,這道題需要用到4個sum變數。考慮每乙個節點sequ[now],令其和為sum,連線到其最左邊的值的
子串的最大和為sum1,連線到其最右邊的值的字串的最大和為sum2,另其連續字串的最大和為sum0。則有以下四個等式:
sequ[now].sum = sequ[2 * now].sum + sequ[2 * now + 1].sum;
sequ[now].sum0 = max(sequ[2 * now].sum2, max(sequ[2 * now].sum2 + sequ[2 *now + 1].sum1, max(sequ[2 *now + 1].sum1,max(sequ[2*now].su
m0,sequ[2*now+1].sum0))));
sequ[now].sum1 = max(sequ[2 * now].sum1, sequ[2 * now].sum + sequ[2 * now + 1].sum1);
sequ[now].sum2 = max(sequ[2 * now + 1].sum2, sequ[2 * now + 1].sum + sequ[2 *now].sum2);
這樣維護的線段樹,就能得到每乙個節點的各個最值。然後在詢問時使用深搜,從下往上,用和更新時同樣的思想,維護不斷連線的區間的各個最值,
最後輸出sum0,便是得到的最值。詳見**。
#include#include#include#include#define max_n 100005
#define max_m 100005
using namespace std;
struct node
};node sequ[4 * max_n + 1000];
stackst;
void build(int x, int l, int r)
}void update(int now, int n, int a)
}void ask(int l, int r, int now) }}
int answer()
else
}return sumt0;
}int main()
for (int i = 0; i < m; i++)
else
}return 0;
}
各種程式設計競賽
noi national olympiad in informatics 全國青少年資訊學奧林匹克競賽由ccf china computer federation 舉辦,此系列由下面幾個賽事組成 icpc international collegiate programming contest 是由...
挑戰程式設計競賽(3)
給定整數a1,a2,an,判斷是否可以從中選出若干數,使他們的和恰好為k。1 n 20 1e8 ai 1e8 1e8 k 1e8 樣例1input 4 1 2 4 7 13 output yes 13 2 4 7 樣例2input 4 1 2 4 7 15 output no dfs include...
《程式設計競賽》學習筆記
棧 stack 最先放入的元素最後被取出 標頭檔案 include stack 常見操作 pop push empty size top 等 include include using namespace std intmain 佇列 queue 最先放入的元素最先被取出 標頭檔案 include ...