洛谷 P4588 TJOI2018 數學計算

2021-10-10 09:34:38 字數 1877 閱讀 7384

小豆現在有乙個數x

xx,初始值為1

11.小豆有q

qq次操作,操作有兩種型別:

一共有t

tt組輸入(t≤

5)

(t \leq 5)

(t≤5);

對於每一組輸入,第一行是兩個數字q,m

od(q

≤100000,m

od

≤1000000000

)q, mod(q \leq 100000,mod\leq 1000000000)

q,mod(

q≤10

0000

,mod

≤100

0000

000)

接下來q

qq行,每一行為操作型別opop

op,操作編號所乘的數字m

mm(保證所有的輸入都是合法的)

1

10 1000000000

1 22 1

1 21 10

2 32 4

1 61 7

1 12

2 7

212

201016

42504

84

本題是線段樹的從模版到應用的入門題

首先建立一棵範圍為 [1,

q]

[1,q]

[1,q

] 的線段樹,並將葉子結點賦值為1,非葉子結點的值為左右兒子結點值的乘積

而線段樹的根節點即為小豆的數字xxx

對於每一次操作1,將線段樹對應的葉子結點(操作編號)修改為乘數mmm,

而根節點就相當於做了一次乘m

mm的操作

對於每一次操作2,則查詢第m操作的葉子結點,將它變為1即可

而根節點就相當於除了第m次操作的數

最後每一次操作完成,查詢一下根節點的值輸出即可

#include

using

namespace std;

typedef

long

long ll;

const ll maxn =

1e5+5;

struct treet[maxn<<2]

;ll t,op,m;

ll q,mod;

void

build

(ll pos,ll l,ll r)

;void

update

(ll pos,ll x,ll k)

;int

main()

}return0;

}void

build

(ll pos,ll l,ll r)

ll mid =

(l+r)

>>1;

build

(pos<<

1,l,mid)

;build

(pos<<1|

1,mid+

1,r)

; t[pos]

.val=1;

return;}

void

update

(ll pos,ll x,ll k)

ll mid=

(l+r)

>>1;

if(x<=mid)

update

(pos<<

1,x,k)

;else

update

(pos<<1|

1,x,k)

; t[pos]

.val=t[pos<<1]

.val*t[pos<<1|

1].val%mod;

return

;}

洛谷P4588 TJOI2018 數學計算

題目大意 有乙個數 x 和取模的數 mod 初始為 1 有兩個操作 m x x times m 並輸出 x mod pos x x 第pos次操作乘的數 保證合法 並輸出 x mod 題解 對時間建一棵線段樹,記錄區間積就可以了 卡點 無 c code include define maxn 100...

P4588 TJOI2018 數學計算

說實話第一眼沒看出來這是個線段樹題 仔細一想就算是你把每次操作計算出來,每次除去找數,然後除掉,那樣就只能最 後取mod,或求很多逆元,不取模你會炸 longlong。如何解決?我們以時間為軸,建立線段樹,葉子結點維護該操作時間的乘數,非葉子結點維護 區間乘,葉子結點一開始都為 1 然後每次乘,進行...

線段樹 P4588 TJOI2018 數學計算

這道題目,看起來只給了乙個數,與線段樹關係不大,但是將每次的操作存起來,就相當於是點更新,段查詢 乘積 這樣就可以轉化為線段樹的問題了。對於操作1,我們可以把對應的位置修改為相應值 操作2,把當前位置,和pos的位置改為1 並維護線段樹即可 includeusing namespace std co...