哈蒙有\(n\)條導線排成一排,每條導線有乙個電阻值,神奇的電光只能從一根導線傳到電阻比它大的上面,而且必須從左邊向右傳導,當然導線不必是連續的。
哈蒙想知道電光最多能通過多少條導線,還想知道這樣的方案有多少。
簡化題意:lis及其方案數,\(a_i \leq n, n \leq 100010\)
最長上公升子串行\(n^2\)顯然很好做,dp入門題。我們再考慮一下如何實現\(n log_2n\)
我們可以用乙個什麼資料結構維護,比如樹狀陣列。
對於乙個需要轉移的\(i\),我們要找的是在\(i\)之前的\(j\),且 滿足\(a_j < a_i\)的\(f_j\)的最大值。
樹狀陣列從左至右加入本就保證\(j\)在\(i\)之前,以\(a_i\)為下標建權值樹狀陣列,維護\(f_i\)字首最大值,這樣找出來的\(f_j\)必定合法且最優,直接轉移即可。
方案數也沒什麼問題。
觀察乙個基本的資料:
\(a_i\)
lis方案數21
1111
4223
2253
4我們可以理解為
最長上公升子串行方案數必定是每層個數的累乘, 而本質就是對於某個長度累加每個方案數,得到下一值的方案數。
而我們只需要在轉移的時候把字首最大值改成累加,注意方案數隨最優值更新。
\(\mathrm\)
#include const int mod = 123456789;
const int n = 200010;
int n, m;
int a[n] = {};
inline int add(int a, int b)
inline void add(int &a, int b)
template void read(t &s)
template void write(t x)
int f[n] = {}, s[n] = {};
struct bit
}inline int ask(int x)
inline int ask(int x)
return sum;
}} t;
main()
write(maxx);
putchar(10);
if (m == 0) return 0;
int ans = 0;
for (int i = 1; i <= n; ++i)
if (f[i] == maxx) add(ans, s[i]);
write(ans);
return 0;
}
2017 8 18訓練日記(樹狀陣列簡述)
今天也就重點看了下樹狀陣列,下面來記一些基礎知識以及和線段樹的對比 主要用於查詢任意兩位之間的所有元素之和,但是每次只能修改乙個元素的值 經過簡單修改可以在log n 的複雜度下進行範圍修改,但是這時只能查詢其中乙個元素的值 如果加入多個輔助陣列則可以實現區間修改與區間查詢 能用樹狀陣列解決的問題,...
樹狀陣列 求和問題題解
題目 求和問題 描述 問題描述 在乙個長度為n的整數數列中取出連續的若干個數,並求它們的和。輸入格式 輸入由若干行組成,第一行有乙個整數n 第二行有n個整數 第三行有乙個整數m 下面m行,每行兩個整數i與j i j 表示求和的起始和終止位置。輸出格式 輸出有m行,每行乙個整數,表示這個數段數列的和。...
一本通 高手訓練 1781 死亡之樹 狀態壓縮dp
link 死亡之樹 關於去重 還是有講究的。題目求本質不同的 具有k個葉子節點的樹的個數 不能上矩陣樹。點數很少容易想到裝壓dp 考慮如何刻畫樹的形狀 發現乙個維度做不了 所以。設狀態 f i j 表示 點的集合為i葉子集合的點為j的方案樹。這樣我們就能知道這棵樹大致的樣子 空間 為 2 當然 如果...