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<bits/stdc++.h>
 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

时间: 2024-10-16 17:00:57

hdu-5475 An easy problem---线段树+取模的相关文章

HDU 5475 An easy problem(线段树)

题目链接: 戳我 题目大意: 一个计算器只有两种运算,初始化 X = 1 第一种操作: X 乘以 一个数,获得新的 X 第二种操作: 当前的 X 除以 一个数 输出  X % M 其中 1 y 表示第一种操作,即 X  = X * y 2 n 表示 X 除以 前面的 第 n 个操作的那个 y,保证 第 n 个表示的是 1,即数据合法 注意:X 在进行操作的时候不要除模, 而是输出的时候除模,即要保证 X 进行操作的时候除模是和不除模情况下是相等的. 比如: 3 10 1 5 1 3 2 1,如果

2015上海网络赛 HDU 5475 An easy problem 线段树

题意就不说了 思路:线段树,维护区间乘积.2操作就将要除的点更新为1. 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 #include<algorithm> 6 #include<queue> 7 #include<vector> 8 #include<set> 9 #include<stri

hud-5475 An easy problem(线段树)

http://acm.hdu.edu.cn/showproblem.php?pid=5475 题意: 原数开始时是1按顺序给你Q个操作,然后其中操作分两种. 1表示将上个操作后的数乘以后面给你的数然后对取余,然后输出结果,2表示除的操作,将现在的数除以指定的先前你所乘上的第几个数 然后对M取模. 思路: 这题用线段树写,断点更新,复杂度是n*(log(n)); 代码: 1 #include<stdio.h> 2 #include<algorithm> 3 #include<i

hdu 5152 A Strange Problem线段树+欧拉函数

*****************************************BC题解**********************************************************************1003 A Strange Problem 对于操作二,利用公式 当x >= Phi(C), A^x = A ^ (x%Phi(C) + Phi(C)) (mod C) 对于2333333这个模数来说,求18次欧拉函数后就变成了1,所以只需要保存19层第三次操作的加数

Gym 101201J Shopping (线段树+取模)

题意:给定 n 个物品,然后有 m 个人买东西,他们有 x 元钱,然后从 l - r 这个区间内买东西,对于每个物品都尽可能多的买,问你最少剩下多少钱. 析:对于物品,尽可能多的买的意思就是对这个物品价格取模,但是对于价格比我的钱还多,那么就没有意义,对取模比我的钱少的,那取模至少减少一半,所以最多只要60多次就可以结束,为了快速找到第一个比我的钱少的,使用线段树. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000"

hdu 4291 A Short problem(矩阵+取模循环节)

A Short problem                                                          Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1785    Accepted Submission(s): 651 Problem Description According to a r

hdu 5443 The Water Problem 线段树

The Water Problem Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5443 Description In Land waterless, water is a very limited resource. People always fight for the biggest source of water. Given a sequence of wat

HDU 5832 A water problem 【大数取模,Java 大数也不是万能的。。】

A water problem Description Two planets named Haha and Xixi in the universe and they were created with the universe beginning. There is 73 days in Xixi a year and 137 days in Haha a year. Now you know the days N after Big Bang, you need to answer whe

HDU 3743 Frosh Week (线段树+离散化)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3743 Frosh Week Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other) Total Submission(s) : 5   Accepted Submission(s) : 1 Font: Times New Roman | Verdana | Georgia Font Size: