給定陣列 和 數字t, 求最大位置k 滿足 sum(1 - k) <= t;
最簡單的想法就是 字首和 + 二分, 每次查詢時間複雜度log(n), 對於數列最左端的資料沒有必要
這裡的倍增可以理解為二分的改良優化版,
設k點為0, p點為1
1. 每次試從當前點k往後加p個數是否小於t
以log速度快速使k逼近答案點
2.隨後再把p值快速縮向條件1, 返回1
當p為零時k即為答案
st演算法是區間倍增儲存資訊的典型例子typedef long long ll;
const int maxn = 1e6 + 10;
ll arr[maxn] = ;
ll brr[maxn] = ;
ll t;
while( cin >> t)
else
p /= 2;
} cout<< k <<'\n';
} return 0;}/*
61 2 3 4 5 6
20 */
樹高log2(n) + 1, 第i行的每個結點儲存從原陣列當前位之後 (1 << (i - 1)) 的最大值
很容易發現最大值不斷傳遞並符合通式 rmq[i][j] = max(rmq[i - 1][j], rmq[i - 1][j + (1 << (i - 1) )]);
查詢時 把區間分成可以交叉的兩部分 l 到 l + 2 ^(k)- 1, 到 r - (1 << k) + 1 到 r 的兩部分取最值即可
輸入, 樹的第零層
預處理 從第二層到第 log2(n) + 1 層int n;
cin >> n;
for(int i = 0; i < n; ++i)
查詢組成區間求最值void init_st(int n)
}}
ll query_st(int fst, int lst)
LCA 二分 倍增
兩個最近的點u和v的最近的公共的祖先稱為最近公共祖先 lca 普通的lca演算法,每算一次lca的時間複雜度為線性o n 這裡講lca 二分的方法。首先對於任意的節點v,利用其父節點的資訊,可以通過par2 v par par v 得到向上走兩步的節點。依此資訊可以通過par4 v par2 par...
NOIP2012 疫情控制 貪心 二分 倍增
一道很全 du 面 liu 的題 題目大意 給定一棵樹,用最少的時間封住這棵樹。題解 首先可以很容易發現乙個條件 軍隊在走的時候都要盡量往上走,但不到根節點。因為越靠近根節點的點,控制的葉子節點越多。不過暴力是肯定會超時的,用倍增優化。題目求的是最長移動時間軍隊的最短時間,想到二分答案。但是還有這樣...
歸納(二) 倍增
把一步一步往上爬變成一次一次向前跳,從 o n o log 的蛻變,可以解決很多問題。anc i k anc anc i k 1 k 1 就這麼一行。我的 2 級祖先就是我 2 級祖先的 2 級祖先。就憑這句話,就可以解決很多問題了。洛谷p1613跑路 小a的工作不僅繁瑣,更有苛刻的規定,要求小a每...