cf834D dp 線段樹區間最值,區間更新

2022-02-19 18:18:56 字數 1487 閱讀 5146

題意: 每個數字代表一種顏色, 乙個區間的美麗度為其中顏色的種數, 給出乙個有 n 個元素的陣列, 問將其分成 k 個區間, 問 k 個區間的美麗度和最大為多少 .

思路: dp + 線段樹區間更新, 區間最值

用 dp[i][j] 儲存前 j 個元素分成 i 個區間的最大美麗度和為多少, 那麼動態轉移方程式為:

dp[i][j] = max(dp[i - 1][k] + gel(k + 1, n)), 其中 i <= k <= n, gel(k + 1, n) 表示區間 [k + 1, n] 的美麗度為多少 .

可以用線段樹來維護 dp[i -1][k] + gel(k + 1, n) 的值, 這部分和 裡面的線段樹用法是一樣的. 建樹時將 sum 初始化為上一輪 dp 的結果. 再遍歷 [i, m] 並將 dp 結果記錄一下即可.

**:

1 #include 2 #include 3

#define lson l, mid, rt << 1

4#define rson mid + 1, r, rt << 1 | 1

5using

namespace

std;67

const

int maxn = 4e4 + 10;8

intpre[maxn], last[maxn], a[maxn];

9int dp[50 + 10][maxn], sum[maxn << 2], lazy[maxn << 2

];10

11void push_up(int

rt)14

15void push_down(int

rt)23}24

25void build(int l, int r, int rt, int

k)31

int mid = (l + r) >> 1;32

build(lson, k);

33build(rson, k);

34push_up(rt);35}

3637

void update(int l, int r, int value, int l, int r, int

rt)43

push_down(rt);

44int mid = (l + r) >> 1;45

if(l <=mid) update(l, r, value, lson);

46if(r >mid) update(l, r, value, rson);

47push_up(rt);48}

4950

int query(int l, int r, int l, int r, int

rt)59

60int main(void)68

for(int i = 1; i <= k; i++)74}

75 printf("

%d\n

", dp[k][n]);

76return0;

77 }

view code

線段樹,區間最值

codeforces 91b queue 線段樹,區間最值 題意是,對於給定區間內的每個元素,要求求出離他最遠的那個元素之間的距離。可以維護乙個線段樹的最小值,每次對於乙個元素,查詢其最右邊的元素的位置。include include include includeusing namespace s...

區間最值與線段樹

區間最值問題 有如下無序序列,求任意子區間段的最大值。接著,我們要用分治的思想來快速地解決上面的問題。在解決問題之前,先介紹一些分治的概念。二分查詢 二分查詢是分治思想的典型運用 我們有如下序列 a1,a2,a3 an.要查詢其中等於b的元素。一種方法就是乙個個對比,看看是不是相等,時間複雜度為n。...

動態區間最值(RMQ) 線段樹

建樹 a aa陣列為初始陣列,tre etree tree 陣列為樹 typedef long long ll const int inf 0x7fffffff const int maxn 2e5 10 int a maxn int tree maxn 2 lz maxn 2 建樹函式 和普通線段...