codeforces 739C 線段樹的高階應用

2021-08-10 20:16:38 字數 1194 閱讀 7001

題意,給你乙個序列,有q次操作,每次對乙個區間進行加值,同時要輸出 最長的上公升序列/下降序列/先上公升再下降序列

很明顯能想到的是利用線段樹維護,有很明顯的能想到要維護線段樹的每個區間的左邊界和右邊界的值,並且每個點都有維護四種變化的值,然後就懵逼了。

這時候應該想到的是維護每個區間的左右邊界的四種情況進行拼湊來更新

一開始想到的是單峰,對於多峰沒想到如何維護,其實也是很簡單,有點類似拼圖或者插頭dp,因為每次子樹的合併會對會造成影響的情況不多,從左邊開始的單調和從左邊開始的雙調還有從右邊開始的單調和從右邊開始的雙調,以及中間的單調和雙調的合併。

可以知道下面的四種情況其實只有可以種處理的,那麼就是 下面貼**,mx1代表單調, mx2代表雙調

l,r代表是從左還是右邊界開始的

#include 

using

namespace

std;

const

int n = 3e5+100;

typedef

long

long ll;

int mx1l[n<<2],mx1r[n<<2],mx2l[n<<2],mx2r[n<<2],mx2[n<<2];

ll vl[n<<2],vr[n<<2],tag[n<<2];

int a[n],sz[n<<2];

void pushdown(int rt)

}void pushup(int rt)

void update(int l,int r,int l,int r,int rt,ll x)

pushdown(rt);

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

if(l<=mid) update(l,r,l,mid,rt<<1,x);

if(r>mid) update(l,r,mid+1,r,rt<<1|1,x);

pushup(rt);

}void build(int l,int r,int rt)

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

build(l,mid,rt<<1);

build(mid+1,r,rt<<1|1);

pushup(rt);

}int main()

}

Codeforces 739B 樹上倍增 差分

思路 差分其實是個自己隨便創造的東西啊 差分 這裡的小差分 比如你要算一棵樹上 u v 路徑上的次數,v是 u 子樹上的乙個點,算一棵樹上 u v 路徑上的次數 在這了是算u v路徑上除了 v 的 每個節點的次數,對於每一對u,v u v 的,用c i 計數,可以c fa u c fa v fa i...

codeforces 463C(對角線技巧)

題意 選取兩個點,分別得到兩個點對應的對角線上的值,要求兩個點走的對角線不能相交,然後求兩個點的對角線的值最大。思路 對於乙個n n,求乙個點的左對角線和右對角線的技巧為 對於a i j 這個點對應的左對角線上的橫座標 縱座標都等於i j,右對角線 的i j n 都相等。例如4 4 的 i j 為左...

739 每日溫度 C

使用單調棧,可以找到乙個元素右邊第乙個比該元素大或者小的元素 vector int dailytemperatures vector int t stk.pop stk.push i return res 但是這裡有乙個巧合,在沒有新增101的前提下,如果乙個元素沒有出棧,就說明在它右邊沒有比它大的...