UOJ 164 線段樹歷史最值

2022-04-29 23:24:08 字數 3776 閱讀 3719

picks博士觀察完金星凌日後,設計了乙個複雜的電阻器。為了簡化題目,題目中的常數與現實世界有所不同。

這個電阻器內有編號為 1∼n1∼n 的 nn 個獨立水箱,水箱呈圓柱形,底面積為 1 m21 m2,每個水箱在頂部和底部各有乙個閥門,可以讓水以 1 m3/s1 m3/s 的流量通過,每個水箱的上閥門接水龍頭,可以無限**水,下閥門不接東西,可以讓水流出。水箱頂部和底部都有乙個介面,水的電阻率為 1 ω⋅m1 ω⋅m。

水箱的高度足夠高,有乙個導電浮標浮在水面上,通過導線與水箱頂的介面相連。一開始時第 ii 個水箱中有 ai m3ai m3 的水。

picks博士接下來就需要對這個複雜的電阻器進行除錯。他會進行以下五種操作。

1、開啟編號在 [l,r][l,r] 中的所有水箱的上方閥門 xx 秒,然後關上它們的上方閥門。

2、開啟編號在 [l,r][l,r] 中的所有水箱的下方閥門 xx 秒,然後關上它們的下方閥門。

3、將編號在 [l,r][l,r] 中的所有水箱的下方閥門與大海通過連通器以一定方式相連,使得這些水箱中都恰擁有 x m3x m3 的水,然後關上它們的下方閥門,撤去連通器。

4、在第 yy 個水箱的上下方介面處接上乙個電動勢為 1 v1 v 的電源,電源沒有內阻,picks博士會測量出通過電源的電流大小,之後撤去該電源。

5、由於水浸泡過的地方會留下明顯的水漬而沒有被水浸泡過的地方不會有,picks博士可以據此測量出此時第 yy 個水箱的水漬高度,以推斷曾經最多有多少水,節約他的建造成本。

現在,他請你來幫他做預實驗,你能告訴他每次測量得到的電流大小以及測量得到的最多的水量是多少嗎?

輸入格式

第一行兩個數:n,mn,m。

接下來一行 nn 個數,第 ii 個數表示初始時第 ii 個水箱內有 ai m3ai m3 的水。

接下來 mm 行中,第 ii 行第乙個數 titi 表示操作型別:

若 ti=1ti=1,則接下來三個整數 li,ri,xili,ri,xi,表示開啟編號在 [li,ri][li,ri] 中的所有水箱的上方介面 xixi 秒。

若 ti=2ti=2,則接下來三個整數 li,ri,xili,ri,xi,表示開啟編號在 [li,ri][li,ri] 中的所有水箱的下方介面 xixi 秒。

若 ti=3ti=3,則接下來三個整數 li,ri,xili,ri,xi,表示將編號在 [li,ri][li,ri] 中的所有水箱與大海連線,使這些水箱中都恰有 xi m3xi m3 的水。

若 ti=4ti=4,則接下來乙個整數 yiyi,表示測量在第 yiyi 個水箱的上下方介面處接上乙個電動勢為 1 v1 v 的電源時通過電源的電流。

若 ti=5ti=5,則接下來乙個整數 yiyi,表示測量此時在第 yiyi 個水箱中的水漬高度。

輸出格式

對於每個 ti=4ti=4,輸出乙個整數表示通過電源的電流大小的倒數(單位為 a−1a−1 ),如果電流為無窮大則輸出0。

對於每個 ti=5ti=5,輸出乙個整數表示在第 yiyi 個水箱中的水漬高度(單位為 mm )。

樣例輸入一

5 6

1 2 3 4 5

2 1 3 2

4 1

1 1 4 1

5 3

3 1 5 4

4 2樣例輸出一

0 3

4樣例輸入二

時間限制:2s2s

空間限制:128mb128mb

測試點編號 n=n= m=m= 約定

1 10001000 10001000

2 10001000 10001000

3 105105 105105 沒有操作2

4 5×1055×105 5×1055×105 沒有操作2

5 105105 105105 沒有操作1與操作5

6 105105 105105 沒有操作1

7 5×1055×105 5×1055×105 沒有操作1

8 5×1055×105 5×1055×105 沒有操作5

9 105105 105105

10 5×1055×105 5×1055×105

對於所有的資料:1≤n,m≤5×105, 0≤ai,xi≤109,1≤li≤ri≤n, 1≤yi≤n1≤n,m≤5×105, 0≤ai,xi≤109,1≤li≤ri≤n, 1≤yi≤n.

提示可能用到的物理公式:

1、歐姆定律:i=uri=ur,其中 i,u,ri,u,r 分別代表電流、電壓和電阻。

2、電阻率公式:r=ρlsr=ρls,其中 r,ρ,l,sr,ρ,l,s 分別代表電阻、電阻率、電阻長度、橫截面積。

用了乙個神奇的標記,網上有很多解釋!!!

1 #include2 #include3 #include4 #include5 #include6 #include7

8using

namespace

std;910

#define lc (o<<1)

11#define rc (o<<1|1)

12#define mid ((l+r)>>1)

13#define ll long long

14#define pb push_back

15#define set(a, v) memset(a, v, sizeof(a))

16#define for(i, a, b) for(int i = (a); i <= (int)(b); i++)

17#define forr(i, a, b) for(int i = (a); i >= (int)(b); i--)

1819

#define inf (1ll<<60)

20#define maxn (500000+5)

2122

void read(int &x)31}

3233

struct#br>br#45};

4647

intql, qr;

4849

struct

seg_tree;

54if(l == r) return

;55 build(lc, l, mid); build(rc, mid+1

, r);56}

5758

void pushdown(int

o);61}62

63void modify(int o, int l, int

r, tage tag)

6768

pushdown(o);

69if(ql <=mid) modify(lc, l, mid, tag);

70if(qr > mid) modify(rc, mid+1

, r, tag);71}

7273 tage query(int o, int l, int r, int pos)

80}st;

8182

intmain());93}

9495

inttype, l, r, rx;

96tage ans;

97ll x;

9899

while(m--));

107else

if(type == 2) st.modify(1, 1, n, (tage));

108else st.modify(1, 1, n, (tage));

109 }else

116}

117118

return0;

119 }

UOJ164 線段樹歷史最值查詢

對於線段樹的歷史查詢我們可以用乙個二元組 定義 a,b 表示 a對b取max 我們用二元組 a,b c,d 分別表示當前以及歷史的標記 注意順序的問題很重要,提醒一下過載運算子會很方便,還要注意負無窮相加得太多會爆,合併時對標記 oo取max很有必要,好像很抽象,那我在 裡注釋一下,防止大家被坑。i...

UOJ164 清華集訓2015 V(線段樹)

首先發現三種操作可以轉化為同樣的形式,定義 x,y x,y x,y 為區間加上x xx後與y yy取max的標記,那麼區間加就是 x,0 x,0 x,0 區間減就是 x 0 x,0 x,0 區間賦值就是 i nf,x inf,x inf,x 這個標記合併也比較方便,在 a,b a,b a,b 標記後...

uoj164 清華集訓2015 V 線段樹

傳送門 begin x max max x a,b a b max max x a a b a b max x a a max b a b end 這裡假設 a,b 是原來的標記,a b 是新加上的標記。考慮如何求歷史的最大值,對於乙個點的最大值 max x a,b 要麼在左邊取到,要麼在右邊取到,...