聽說這是「極長上公升序列」。。。我們可以把題中的圖改一下,把左側的一排視為編號,此位置的值就是此點在右側連的點的編號。
這樣問題就變成乙個序列了。很明顯選乙個點就會覆蓋它之前權值比他大的點以及它之後權值比他小的點。
設f[i]為最後乙個選的是i,且i之前的全被覆蓋時的最小花費。很容易發現,如果f[i]要從之前的f[j]轉移過來,那麼a[j]一定比a[i]小,否則i已經被j覆蓋了。而且,a[j]一定是區間[j,i-1]裡,比a[i]小的值裡最大的乙個。因為如果j右側有乙個點k,k的權值比j大,那麼選j就不能覆蓋k,而且a[k]
#include
#include
#include
#include
#define n 200005
#define inf 1000000000
using namespace std;
int n;
struct nodehh[n];
namespace tree
t[n*4];
inline void build(int l,int r,int x)
int ans,h;
inline int calc(int g,int x)
inline void add(int l,int k,int k,int x)
int mid=t[x].l+t[x].r>>1;
if(l<=mid)add(l,k,k,x*2);
else add(l,k,k,x*2+1);
t[x].h=max(t[x*2].h,t[x*2+1].h);
t[x*2].lc=calc(t[x*2+1].h,x*2);
}inline void q(int l,int r,int x)
int mid=t[x].l+t[x].r>>1;
if(r>mid)q(l,r,x*2+1);
if(l<=mid)q(l,r,x*2);
}}using namespace tree;
bool cmp(node a,node b){return a.a
線段樹 模板題
problem description 已知乙個數列,你需要進行下面兩種操作 1.將某區間每乙個數加上x 2.求出某區間每乙個數的和 input 第一行包含兩個整數n m,分別表示該數列數字的個數和操作的總個數。第二行包含n個用空格分隔的整數,其中第i個數字表示數列第i項的初始值。接下來m行每行包含...
線段樹(模板題)
對於一條數鏈,二分,然後二分,然後再二分 給定一數列,規定有兩種操作,一是修改某個元素,二是求區間的連續和。數列元素初始化為0 輸入 輸入資料第一行包含兩個正整數n,m n 100000,m 500000 以下是m行,每行有三個正整數k,a,b k 0或1,a,b n k 0時表示將a處數字加上b,...
線段樹 題集
扶蘇學長給我們講了線段樹 樹狀陣列 主席樹等資料結構 並發布了練習題單 題目 a 只需將maketag函式更改為異或和即可 然後tag的更新方式更改 include include include using namespace std const long long k 5e5 5 long lo...