hdu-5475 An easy problem---线段树+取模

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=5475

题目大意:

给X赋初值1,然后给Q个操作,每个操作对应一个整数M;

如果操作是1则将X乘以对应的M,

如果是2则除以第M次操作对应的M',求每次操作后X的值对给定值取摸的结果。

解题思路:

第一眼看这道题,以为就是水题,直接模拟暴力呀,但是发现这样是错误的,因为这里有除法,对除法取模,就应该是逆元,但是逆元不一定存在

想了之后发现可以用线段树保存每一个要乘以的数字,对于操作一就加入数字即可,操作二就对第M次操作的数字进行标记,不让他参与乘法运算,每次输出tree[1]的值就可以了。

线段树维护两个值,一个为标记,一个是区间内的数字的积,对于操作一,更新叶节点,并且更新其父节点。对于操作2也是更新叶节点,标记他,更新父节点时,不让标记过的叶节点参与乘法运算。

 1 #include
 2 #define MID(l, r) (l + (r - l) / 2)
 3 #define lc (o<<1)
 4 #define rc (o<<1|1)
 5 using namespace std;
 6 typedef long long ll;
 7 int n, m;
 8 const int maxn = 100000 + 10;
 9 struct node
10 {
11     bool flag;
12     ll num;
13     int l, r;
14 }tree[maxn << 2];
15 void build(int o,int l, int r)
16 {
17     tree[o].l = l, tree[o].r = r;
18     tree[o].flag = 1;
19     if(l == r)
20     {
21         tree[o].num = 1;
22         return;
23     }
24     int m = MID(l ,r);
25     build(lc, l, m);
26     build(rc, m + 1, r);
27     tree[o].num = 1;
28     if(tree[lc].flag)tree[o].num = tree[o].num * tree[lc].num % m;
29     if(tree[rc].flag)tree[o].num = tree[o].num * tree[rc].num % m;
30 }
31 int flag;
32 int p, v;
33 void update(int o)
34 {
35     if(tree[o].l == tree[o].r)
36     {
37         if(flag)
38         {
39             tree[o].flag = 1;
40             tree[o].num = v;
41         }
42         else
43         {
44             tree[o].flag = 0;
45         }
46         return;
47     }
48     if(p <= tree[lc].r)update(lc);
49     else update(rc);
50     tree[o].num = 1;
51     if(tree[lc].flag)tree[o].num = tree[o].num * tree[lc].num % m;
52     if(tree[rc].flag)tree[o].num = tree[o].num * tree[rc].num % m;
53 }
54 int main()
55 {
56     int T, cases = 0;
57     cin >> T;
58     while(T--)
59     {
60         printf("Case #%d:\n", ++cases);
61         scanf("%d%d", &n, &m);
62         int a, b;
63         build(1, 1, n);
64         for(int i = 1; i <= n; i++)
65         {
66             scanf("%d%d", &a, &b);
67             if(a == 1)
68             {
69                 flag = 1;
70                 p = i, v = b;
71             }
72             else
73             {
74                 flag = 0;
75                 p = b;
76             }
77             update(1);
78             printf("%lld\n", tree[1].num);
79         }
80     }
81     return 0;
82 }

 

转载于:https://www.cnblogs.com/fzl194/p/9040396.html

你可能感兴趣的:(hdu-5475 An easy problem---线段树+取模)