老管家是乙個聰明能幹的人。他為財主工作了整整10年,財主為了讓自已賬目更加清楚。要求管家每天記k次賬,由於管家聰明能幹,因而管家總是讓財主十分滿意。但是由於一些人的挑撥,財主還是對管家產生了懷疑。於是他決定用一種特別的方法來判斷管家的忠誠,他把每次的賬目按1,2,3…編號,然後不定時的問管家問題,問題是這樣的:在a到b號賬中最少的一筆是多少?為了讓管家沒時間作假他總是一次問多個問題。
關於線段樹的詳細講解可以參考拙作(點選傳送門):【演算法微解讀】**線段樹
那麼我們就開始講解一下這一道模板題,題目的主要意思就是區間查詢最小值。
首先定義線段樹的節點的狀態segment_tree_node
struct segment_tree_nodetree[maxn];
接下來就是建樹build
的過程了。
void build(int l,int r,int nod)
int mid=(l+r)>>1;//取中間mid
build(l,mid,lson); build(mid+1,r,rson);//lson和rson可以恆定義一下,縮短**
pushup(nod);//更新父節點
}
建樹好之後,我們要進行一下區間查詢的操作,區間查詢的本質其實就是將原區間分成兩部分,然後對每乙個區間的目標區間進行查詢。
|----l----|----r----|
當做是原區間
注:區間查詢一般是不需要pushup的,但是如果之前是有區間修改,那麼是要pushdown的。那麼我們通過**來詳細的看一下區間查詢最小值是如何寫的。
int query(int l,int r,int ll,int rr,int nod)
主程式就不寫了,也是很簡單的
恆定義:define lson nod<<1 define rson (nod<<1)+1
#include #define lson nod<<1
#define rson (nod<<1)+1
#define ms(a,b) memset(a,b,sizeof(a))
using namespace std;
const int maxn=100000<<2;
const int inf=1<<30;
struct segment_tree_nodetree[maxn];
int n,m;
int a[maxn>>2];
inline int read()
while (isdigit(ch))
return w?-x:x;
}void pushup(int nod)
void build(int l,int r,int nod)
int mid=(l+r)>>1;//取中間mid
build(l,mid,lson); build(mid+1,r,rson);//lson和rson可以恆定義一下,縮短**
pushup(nod);//更新父節點
}int query(int l,int r,int ll,int rr,int nod)
int main()
return 0;
}
洛谷P1816 忠誠
老管家是乙個聰明能幹的人。他為財主工作了整整10年,財主為了讓自已賬目更加清楚。要求管家每天記k次賬,由於管家聰明能幹,因而管家總是讓財主十分滿意。但是由於一些人的挑撥,財主還是對管家產生了懷疑。於是他決定用一種特別的方法來判斷管家的忠誠,他把每次的賬目按1,2,3 編號,然後不定時的問管家問題,問...
洛谷P1816 忠誠 分塊
分塊真的是很暴力呀 暴力查詢左端,暴力查詢又端點,中間整體部分直接 o 1 求出。注意程式設計細節 belong i i 1 block 1 這樣可以保證序列被分成這樣的 code include include include includeusing namespace std const in...
倍增 rmq 忠誠 洛谷P1816
老管家是乙個聰明能幹的人。他為財主工作了整整10年,財主為了讓自已賬目更加清楚。要求管家每天記k次賬,由於管家聰明能幹,因而管家總是讓財主十分滿意。但是由於一些人的挑撥,財主還是對管家產生了懷疑。於是他決定用一種特別的方法來判斷管家的忠誠,他把每次的賬目按1,2,3 編號,然後不定時的問管家問題,問...