序列 莫隊 dp預處理

2022-05-19 06:14:42 字數 2172 閱讀 6734

《更新提示》

《第一次更新》

《正文》

給定長度為n的序列:a1,a2,…,an,記為a[1:n]。

類似地,a[l:r](1≤l≤r≤n)是指序列:al,al+1,…,ar-1,ar。若1≤l≤s≤t≤r≤n,則稱a[s:t]是a[l:r]的子串行。

現在有q個詢問,每個詢問給定兩個數l和r,1≤l≤r≤n,求a[l:r]的不同子串行的最小值之和。

例如,給定序列5,2,4,1,3,詢問給定的兩個數為1和3,那麼a[1:3]有6個子序列a[1:1],a[2:2],a[3:3],a[1:2],a[2:3],a[1:3],這6個子序列的最小值之和為5+2+4+2+2+2=17。

輸入檔案的第一行包含兩個整數n和q,分別代表序列長度和詢問數。

接下來一行,包含n個整數,以空格隔開,第i個整數為ai,即序列第i個元素的值。

接下來q行,每行包含兩個整數l和r,代表一次詢問。

對於每次詢問,輸出一行,代表詢問的答案。

5 5

5 2 4 1 3

1 5

1 3

2 4

3 5

2 5

28 

17 11

11 17

回答若干個靜態的區間詢問,思路是莫隊。

假設我們已經得到了區間\([l,r]\)的答案,直接考慮如何轉移到\([l,r+1]\)。顯然,我們只需要考慮包含\(r+1\)這乙個點的子串行\([l,r+1],[l+1,r+1],...,[r+1,r+1]\)即可。要求的是最小值之和,我們就設\([l,r+1]\)在\(a\)序列上的區間最小值為\(a_p\),位置是\(p\),那麼所有左端點在\([l,p]\)之間的區間的答案就都是\(a_p\),總共的貢獻為\(a_p*(p-l+1)\),這個問題顯然可以用\(st\)表解決。

那麼剩下的那些區間我們考慮用\(dp\)來計算答案。設\(f[i][j]\)代表右端點為\(j\),左端點在\([i,j]\)之間的答案之和,那麼我們要求的就是\(f[p+1][r+1]\)。記錄下\(prep_i\)代表\(a\)序列中\(a_i\)左邊第乙個比他小的元素的位置(單調棧解決),狀態轉移方程就是:$$f[i][j]=f[i][prep_j]+a_j*(j-prep_j)$$。

發現狀態轉移方程與\(i\)無關,直接將第一維捨去,那麼\(f[j]\)的定義就是右端點為\(j\)的所有區間的答案之和。繼續考慮原問題,發現必然存在乙個點\(x\)滿足\(prep_x=p\),\(f[r+1]=a_*(r+1-prep_)+...+a_x*(x-p)+f[p]\),那麼我們原來要求的\(f[p+1][r+1]\)其實可以表示為\(f[r+1]-f[p]\),然後預處理出\(f\)陣列,就可在莫隊當中\(o(1)\)轉移了。

當然,我們還需要處理出反方向的\(f\)陣列,以便莫隊向左轉移。如果是刪除操作的話,就減去加入這個點的時候帶來的貢獻即可。

\(code:\)

#include using namespace std;

const int n = 100200 , maxlogn = 25 , inf = 2e9;

int n,m,a[n],size;

int min[n][maxlogn],log2[n],pow2[maxlogn];

int prep[n],next[n],stack[n],top;

long long ans[n],fl[n],fr[n],tot;

struct queryq[n];

inline void init(void)

while ( top )

}inline int query(int l,int r)

inline void input(void)

inline void dp(void)

inline bool compare(query p1,query p2)

inline void insert1(int l,int r)

inline void insert2(int l,int r)

inline void remove1(int l,int r)

inline void remove2(int l,int r)

inline void captainmo(void)

}int main(void)

《後記》

pad sequences序列預處理

用法 pad sequences tf.contrib.keras.preprocessing.sequence.pad sequences keras.preprocessing.sequence.pad sequences sequences,maxlen none,dtype int32 pa...

pad sequences序列預處理

用法 pad sequences tf.contrib.keras.preprocessing.sequence.pad sequences keras.preprocessing.sequence.pad sequences sequences,maxlen none,dtype int32 pa...

hdu 4358 莫隊演算法 dfs序列

解題思路 用dfs求出整棵樹的dfs序列,這樣以u為根節點的子樹就轉化到相對應的區間上了。由於是區間不修改查詢問題,這個時候就可以用莫隊演算法了。pragma comment linker,stack 16777216 include include include include includeu...