旅行傳送門:
小豆現在有乙個數 x,初始值為 1。小豆有 q 次操作,操作有兩種型別:
1 m
:將 x變為 x * m,並輸出 x mod m
2 pos
:將 x變為 x 除以第 pos次操作所乘的數(保證第 pos次操作一定為型別 1,對於每乙個型別 1 的操作至多會被除一次),並輸出 x mod m。
一共有 t組輸入。
對於每一組輸入,第一行是兩個數字 q,m。
接下來 q行,每一行為操作型別 op,操作編號或所乘的數字 m(保證所有的輸入都是合法的)。
對於每乙個操作,輸出一行,包含操作執行後的 x mod m的值。
輸入 #1複製
1輸出 #1複製10 1000000000
1 22 1
1 21 10
2 32 4
1 61 7
1 12
2 7
212對於 20% 的資料,1 ≤ q ≤ 500。201016
42504
84
對於 100% 的資料,1 ≤ q ≤ 10^5,t ≤ 5,m ≤ 10^9。
第一眼看去,就只對乙個數進行操作,這哪是甚麼線段樹的題,直接上暴力模擬不就完事了(上了就去見祖宗,哪怕開long long也直接親ma炸穿)(雖然純當作數論題做也不是不行)。
但轉念一想,藍題不可能這麼水,重新審題,題目中有兩個操作,一是x乘以乙個值,另乙個是x除以之前乘過的某個值;乘以乙個數又除以乙個數,相當於啥也沒乾,也就可以看成是回溯操作。那麼我們不妨以時間為軸建立一棵範圍為[1,q]的線段樹,第k個葉子節點的序號表示這是第pos次操作,其儲存的值表示x在這次操作中乘以的數。此時第一種操作變為給當前葉節點賦值m,第二種操作變為令第pos個葉節點的值回溯至1,根節點的值就是每次操作執行後x的值。
總的來說是道很有意思的題_(:з」∠)_
1 #include 2view code#define for(i, j, k) for (int i = (j); i <= (k); i++)
3#define maxq 100000 + 10
45 typedef long
long
ll;6
7ll t, q, mod;
8 ll tree[maxq << 2];9
10ll read()
1120
while (ch >= '
0' && ch <= '9'
)2125return x *f;26}
2728
void
build(ll k, ll l, ll r)
2937
38void
update(ll k, ll l, ll r, ll pos, ll x)
3945 ll mid = (l + r) >> 1;46
if (pos <=mid)
47 update(k << 1
, l, mid, pos, x);
48else
49 update(k << 1 | 1, mid + 1
, r, pos, x);
50 tree[k] = ((tree[k << 1] % mod) * (tree[k << 1 | 1] % mod)) %mod;51}
5253
int main(int argc, char
const *ar**)
5469
else
7075}76
}77return0;
78 }
P4588 TJOI2018 數學計算
說實話第一眼沒看出來這是個線段樹題 仔細一想就算是你把每次操作計算出來,每次除去找數,然後除掉,那樣就只能最 後取mod,或求很多逆元,不取模你會炸 longlong。如何解決?我們以時間為軸,建立線段樹,葉子結點維護該操作時間的乘數,非葉子結點維護 區間乘,葉子結點一開始都為 1 然後每次乘,進行...
線段樹 P4588 TJOI2018 數學計算
這道題目,看起來只給了乙個數,與線段樹關係不大,但是將每次的操作存起來,就相當於是點更新,段查詢 乘積 這樣就可以轉化為線段樹的問題了。對於操作1,我們可以把對應的位置修改為相應值 操作2,把當前位置,和pos的位置改為1 並維護線段樹即可 includeusing namespace std co...
洛谷 P4588 TJOI2018 數學計算
小豆現在有乙個數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 1000000...