P4588 [TJOI2018]数学计算 (线段树)

用线段树维护操作序列,叶子结点存要乘的数,非叶子结点存区间乘积,每次输出tr[1] 就是答案。

 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 #define lson k << 1, l, mid
 4 #define rson k << 1 | 1, mid + 1, r
 5 #define ls k << 1
 6 #define rs k << 1 | 1
 7 #define mid ((l + r) >> 1)
 8 using namespace std;
 9 const int maxn = 100005;
10 ll tr[maxn << 2];
11 int mod, t, q;
12 
13 void update(int k) {
14     tr[k] = (tr[ls] * tr[rs]) % mod;
15 }
16 
17 void build(int k, int l, int r) {
18     tr[k] = 1;
19     if (l == r) return ;
20     build(lson), build(rson);
21 }
22 
23 void change(int k, int l, int r, int x, int val) {
24     if (l == r) {
25         tr[k] = (val == 0) ? 1 : val;
26         return ;
27     } 
28     if (x <= mid) change(lson, x, val);
29     else change(rson, x, val);
30     update(k);
31 }
32 
33 int main() {
34     scanf("%d", &t);
35     while (t--) {
36         scanf("%d %d", &q, &mod);
37         build(1, 1, q);
38         int opt, x;
39         for (int i = 1; i <= q; i++) {
40             scanf("%d %d", &opt, &x);
41             if (opt == 1) change(1, 1, q, i, x), printf("%lld\n", tr[1] % mod);
42             else change(1, 1, q, x, 0), printf("%lld\n", tr[1] % mod);
43         }
44     }
45     return 0;
46 }

 

posted @ 2022-07-28 14:16  YHXo  阅读(32)  评论(0)    收藏  举报