模板 二分 倍增及其應用

2022-05-10 02:45:43 字數 1057 閱讀 4903

給定陣列 和 數字t, 求最大位置k 滿足 sum(1 - k) <= t;

最簡單的想法就是 字首和 + 二分, 每次查詢時間複雜度log(n), 對於數列最左端的資料沒有必要

這裡的倍增可以理解為二分的改良優化版,

設k點為0, p點為1

1. 每次試從當前點k往後加p個數是否小於t

以log速度快速使k逼近答案點

2.隨後再把p值快速縮向條件1, 返回1

當p為零時k即為答案

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 */

st演算法是區間倍增儲存資訊的典型例子

樹高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 的兩部分取最值即可

輸入, 樹的第零層

int n;

cin >> n;

for(int i = 0; i < n; ++i)

預處理 從第二層到第 log2(n) + 1 層

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每...