题目描述

小豆现在有一个数\(x\),初始值为\(1\).小豆有\(Q\)次操作,操作有两种类型:

\(1\;m\):\(x=x\times m\)输出\(x\%mod\);

\(2\;pos\):\(x= x/\)第\(pos\)次操作所乘的数(保证第\(pos\)次操作一定为类型\(1\),对于每一个类型\(1\)的操作至多会被除一次)输出\(x\%mod\);

输入格式

一共有\(t\)组输入(\(t\leq5\));

对于每一组输入,第一 行是两个数字\(Q,mod\)(\(Q\leq100000,mod\leq100000000\));

接下来\(Q\)行,每一行为操作类型\(op\),操作编号或所乘的数字\(m\)(保证所有的输入都是合法的).

输出格式

对于每一个操作,输出一行,包含操作执行后的\(x\%mod\)的值

输入输出样例

输入 #1

  1. 1
  2. 10 1000000000
  3. 1 2
  4. 2 1
  5. 1 2
  6. 1 10
  7. 2 3
  8. 2 4
  9. 1 6
  10. 1 7
  11. 1 12
  12. 2 7

输出 #1

  1. 2
  2. 1
  3. 2
  4. 20
  5. 10
  6. 1
  7. 6
  8. 42
  9. 504
  10. 84

说明/提示

对于\(20\%\)的数据,\(1\leq Q\leq500\)

对于\(100\%\)的数据,\(1\leq Q\leq100000\)

题解

这道题目难在思维,难在怎么想到线段树。

暴力模拟很容易想到,但是,在此题中,暴力模拟是错误的!!!

一组\(\texttt{hack}\)数据:

  1. 1
  2. 2 10
  3. 1 99
  4. 2 99

输出应为:

  1. 9
  2. 1

貌似用高精度就可以了,但空间复杂度感人……~~

这里直接讲正解。

用一颗线段树维护操作的区间乘积,如果是\(1\)操作就将当前节点的值改为\(m\),\(2\)操作就把要除的数所在的节点的值改为\(1\)。

输出的话……直接输出线段树根节点的值即可。

代码

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <cstdlib>
  5. #include <cmath>
  6. #include <algorithm>
  7. #define int long long//注意long long
  8. #define itn int
  9. #define gI gi
  10. using namespace std;
  11. inline int gi()//快读
  12. {
  13. int f = 1, x = 0; char c = getchar();
  14. while (c < '0' || c > '9') {if (c == '-') f = -1; c = getchar();}
  15. while (c >= '0' && c <= '9') {x = x * 10 + c - '0'; c = getchar();}
  16. return f * x;
  17. }
  18. int t, q, mod, tr[400003], ans;
  19. inline int ls(int p) {return p << 1;}//左儿子
  20. inline int rs(itn p) {return p << 1 | 1;}//右儿子
  21. void modify(int ql, int qr, int z, int l, int r, int p)//修改节点
  22. {
  23. if (l == r && l == ql) {tr[p] = z; return;}//到了叶子节点进行修改
  24. int mid = (l + r) >> 1;
  25. if (ql <= mid) modify(ql, qr, z, l, mid, ls(p));//递归左子树
  26. if (qr > mid) modify(ql, qr, z, mid + 1, r, rs(p));//递归右子树
  27. tr[p] = (tr[ls(p)] % mod * tr[rs(p)] % mod) % mod;//上传节点
  28. return;
  29. }
  30. signed main()
  31. {
  32. t = gi();
  33. while (t--)
  34. {
  35. q = gi(), mod = gi();
  36. for (int i = 1; i <= 400001; i+=1) tr[i] = 1;//注意,本题中不需要建树,只需要把所有节点的值设为1
  37. for (int i = 1; i <= q; i+=1)
  38. {
  39. int op = gi(), m = gi();
  40. if (op == 1) modify(i, i, m, 1, q, 1);//操作1,将第i个点的值修改为m
  41. else modify(m, m, 1, 1, q, 1);//操作2,将第m个点的值修改为1
  42. printf("%lld\n", tr[1]);//输出
  43. }
  44. }
  45. return 0;
  46. }

题解【洛谷P4588】[TJOI2018]数学计算的更多相关文章

  1. 洛谷P4588 [TJOI2018]数学计算 【线段树】

    题目链接 洛谷P4588 题解 用线段树维护即可 #include<algorithm> #include<iostream> #include<cstring> ...

  2. [洛谷P4588][TJOI2018]数学计算

    题目大意:有一个数$x$和取模的数$mod$,初始为$1$,有两个操作: $m:x=x\times m$并输出$x\% mod$ $pos:x=x/第pos次操作乘的数$(保证合法),并输出$x\%m ...

  3. 洛谷P4588 [TJOI2018]数学计算(线段树)

    题意 题目链接 Sol TJOI怎么全是板子题 对时间开个线段树,然后就随便做了.... #include<bits/stdc++.h> using namespace std; cons ...

  4. 【题解】Luogu P4588 [TJOI2018]数学计算

    原题传送门 这题是线段树的模板题 显而易见,直接模拟是不好模拟的(取模后就不好再除了) 我们按照时间来建一颗线段树 线段树初始值都为1,用来维护乘积 第一种操作就在当前时间所对应的节点上把乘数改成m ...

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

    用线段树维护操作序列,叶子结点存要乘的数,非叶子结点存区间乘积,每次输出tr[1] 就是答案. 1 #include<bits/stdc++.h> 2 #define ll long lo ...

  6. 洛谷试炼场-简单数学问题-P1045 麦森数-高精度快速幂

    洛谷试炼场-简单数学问题 B--P1045 麦森数 Description 形如2^P−1的素数称为麦森数,这时P一定也是个素数.但反过来不一定,即如果PP是个素数,2^P-1 不一定也是素数.到19 ...

  7. 洛谷试炼场-简单数学问题-P1403 [AHOI2005]-因数

    洛谷试炼场-简单数学问题 P1403 [AHOI2005]约数研究 Description 科学家们在Samuel星球上的探险得到了丰富的能源储备,这使得空间站中大型计算机"Samuel I ...

  8. 洛谷试炼场-简单数学问题-P1088 火星人

    洛谷试炼场-简单数学问题 A--P1088 火星人 Description 人类终于登上了火星的土地并且见到了神秘的火星人.人类和火星人都无法理解对方的语言,但是我们的科学家发明了一种用数字交流的方法 ...

  9. 洛谷 P4593 [TJOI2018]教科书般的亵渎

    洛谷 P4593 [TJOI2018]教科书般的亵渎 神仙伯努利数...网上一堆关于伯努利数的东西但是没有证明,所以只好记结论了? 题目本质要求\(\sum_{i=1}^{n}i^k\) 伯努利数,\ ...

  10. BZOJ5334: [Tjoi2018]数学计算

    BZOJ5334: [Tjoi2018]数学计算 https://lydsy.com/JudgeOnline/problem.php?id=5334 分析: 线段树按时间分治即可. 代码: #incl ...

随机推荐

  1. 对于tensorflow中的gradient_override_map函数的理解

    # #############添加############## def binarize(self, x): """ Clip and binarize tensor u ...

  2. PAT (Advanced Level) Practice 1019 General Palindromic Number (20 分) (进制转换,回文数)

    A number that will be the same when it is written forwards or backwards is known as a Palindromic Nu ...

  3. C#接口与抽象类学习笔记

    本笔记摘抄自:https://www.cnblogs.com/solan/archive/2012/08/01/CSharp06.html,记录一下学习过程以备后续查用. 摘要: 抽象类:是一种特殊的 ...

  4. 异常处理_python

    一.异常处理格式: name=[1,2]data={}try: name[3] data['name']except (KeyError,IndexError) as e : #捕捉指定的几个错误类型 ...

  5. oracle sql 数据库之间导入数据

    1.导入别的表 insert into EMPI_IDENTIFY select id,empiid, name||':' ||idcardno,'accidcardno','' from empi_ ...

  6. npm 模块开发调试技巧之最优方案npm link

    在我们平时写项目中,当我们需要新开发或修改的 npm 模块时,如何在本地项目中调试呢? 本地项目路径:G:\npm\project 开发的模块路径:G:\npm\model 方法一: 在cmd命令窗口 ...

  7. <软件工程基础>个人项目——数独

    参见GitHub:https://github.com/1773262526/Software-Foundation Personal Software Process Stages         ...

  8. Python入门5 —— 基本运算符

    1.算数运算符('+'.'-'.'*'.'/'.'//'.'%'.'**') print(10 + 3) -- 输出:13 print(10 - 3) -- 输出:7 print(10 * 3) -- ...

  9. SaltStack之return与job管理

    目录 1. SaltStack组件之return 1.1 return流程 1.2 使用mysql作为return存储方式 2. job cache 2.1 job cache流程 2.2 job管理 ...

  10. c语言修炼之一

    1.C项目要高内聚(模块功能必须明确,一个模块完成一个功能).低耦合(接口尽可能简单,减少各模块间的联系). 2.register类型不能为模块间的全局变量.模块内的全局变量.局部static变量.( ...