思路来源:Zed222

如果一个区间里的数都有这个质数,那么我们就直接利用性质\(\phi(n * p) = \phi(n) * p\),如果没有这个区间中有没有这个质数的,那么就退化到了单点修改,当时比赛的时候,队伍感觉就没有了头绪,而今天补题发现确实是单点修改,并且代码跑的飞快,具体的证明就不深究了,还有当时并不会存以一个区间里存在有哪些质数(维护区间有哪些质数,\(pushup\)的时候我们用与操作),然后通过做了CF. Please, another Queries on Array?这道题学到\(300\)以内只有六十一个质数,所以可以用状压的方式存,而本题\(100\)以内的质数有二十多个,也采用状压的方式。

进入正题:

  • 当一个区间里的数都有这个质数的时候,直接利用性质\(\phi(n \times p) = \phi(n) \times p\),然后\(\sum\limits_{i = l}^{r}\phi(x_i \times p^k) = p^k \times \sum\limits_{i = l}^{r}\phi(x_i)\)。

  • 否则进行单点修改,当tr[u].l == tr[u].r时,进行单点修改。

    为了单点修改方便,我们利用算术基本定理化简一下式子:\(\phi(n) = n \times \prod\limits \cfrac{(p_i - 1)}{p_i} = \prod\limits (p_i - 1) \times p_i^{a_{i - 1}}\)。

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. typedef long long LL;
  4. const int N = 1E5 + 10, Mod = 998244353, M = 105;
  5. int euler[M], cntp, primes[M], state[M];
  6. int a[N];
  7. int cnt[M][30];
  8. bitset<30> st[M];
  9. struct SegMentTree {
  10. int l, r;
  11. LL sum;
  12. LL laz;
  13. bitset<30> has;
  14. }tr[N * 4];
  15. void get_euler(int n) {
  16. euler[1] = 1;
  17. for (int i = 2; i <= n; i++) {
  18. if (!state[i]) primes[cntp++] = i, euler[i] = i - 1;
  19. for (int j = 0; primes[j] <= n / i; j++) {
  20. state[i * primes[j]] = true;
  21. if (i % primes[j] == 0) {
  22. euler[i * primes[j]] = euler[i] * primes[j];
  23. break;
  24. }
  25. euler[i * primes[j]] = euler[i] * (primes[j] - 1);
  26. }
  27. }
  28. }
  29. LL qmi(LL a, LL b, LL Mod) {
  30. LL res = 1ll;
  31. while (b) {
  32. if (b & 1) res = res * a % Mod;
  33. b >>= 1;
  34. a = a * a % Mod;
  35. }
  36. return res % Mod;
  37. }
  38. void pushup(int u) {
  39. tr[u].sum = (tr[u << 1].sum + tr[u << 1 | 1].sum) % Mod;
  40. tr[u].has = tr[u << 1].has & tr[u << 1 | 1].has;
  41. }
  42. void pushdown(int u) {
  43. auto &root = tr[u], &left = tr[u << 1], &right = tr[u << 1 | 1];
  44. if (root.laz == 1) return;
  45. left.sum = left.sum * root.laz % Mod;
  46. right.sum = right.sum * root.laz % Mod;
  47. left.laz = left.laz * root.laz % Mod;
  48. right.laz = right.laz * root.laz % Mod;
  49. root.laz = 1;
  50. }
  51. void build(int u, int l, int r) {
  52. if (l == r) {
  53. tr[u] = {l, r, euler[a[l]], 1ll, st[a[l]]};
  54. return;
  55. }
  56. tr[u] = {l, r}, tr[u].laz = 1ll;
  57. int mid = l + r >> 1;
  58. build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
  59. pushup(u);
  60. }
  61. void modify(int u, int l, int r, int k, int ct) {
  62. int p = primes[k];
  63. if (tr[u].l >= l && tr[u].r <= r && tr[u].has[k]) { //当前区间有这个质因子
  64. tr[u].sum = tr[u].sum * qmi(p, ct, Mod) % Mod;
  65. tr[u].laz = tr[u].laz * qmi(p, ct, Mod) % Mod;
  66. } else if (tr[u].l == tr[u].r) { //直至单点修改
  67. tr[u].has[k] = 1;
  68. tr[u].sum = tr[u].sum * (p - 1) % Mod;
  69. tr[u].sum = tr[u].sum * qmi(p, ct - 1, Mod) % Mod;
  70. } else {
  71. pushdown(u);
  72. int mid = tr[u].l + tr[u].r >> 1;
  73. if (l <= mid) modify(u << 1, l, r, k, ct);
  74. if (r > mid) modify(u << 1 | 1, l, r, k, ct);
  75. pushup(u);
  76. }
  77. }
  78. LL query(int u, int l, int r) {
  79. if (tr[u].l >= l && tr[u].r <= r) {
  80. return tr[u].sum;
  81. } else {
  82. pushdown(u);
  83. int mid = tr[u].l + tr[u].r >> 1;
  84. LL res = 0;
  85. if (l <= mid) res = (res + query(u << 1, l, r)) % Mod;
  86. if (r > mid) res = (res + query(u << 1 | 1, l, r)) % Mod;
  87. return res;
  88. }
  89. }
  90. int main() {
  91. get_euler(100);
  92. for (int i = 1; i <= 100; i++) {
  93. for (int j = 0; j < cntp; j++) {
  94. if (i % primes[j] == 0) {
  95. int s = 0, temp = i;
  96. while (temp % primes[j] == 0) s++, temp /= primes[j];
  97. cnt[i][j] = s;
  98. st[i][j] = (cnt[i][j] > 0);
  99. }
  100. }
  101. }
  102. int n, m;
  103. scanf("%d%d", &n, &m);
  104. for (int i = 1; i <= n; i++) {
  105. scanf("%d", &a[i]);
  106. }
  107. build (1, 1, n);
  108. while (m--) {
  109. int op, l, r;
  110. scanf("%d%d%d", &op, &l, &r);
  111. if (op == 0) {
  112. int w;
  113. scanf("%d", &w);
  114. for (int i = 0; i < cntp; i++) {
  115. if (cnt[w][i]) {
  116. modify(1, l, r, i, cnt[w][i]);
  117. }
  118. }
  119. } else {
  120. printf("%lld\n", query(1, l, r));
  121. }
  122. }
  123. return 0;
  124. }

The 2021 ICPC Asia Regionals Online Contest (II) L Euler Function的更多相关文章

  1. 2021ICPC网络赛第一场部分题解-The 2021 ICPC Asia Regionals Online Contest (I)

    写在前面 本来应该6题的,结果不知道哪个铸币发了H的clar,当即把我们的思路转向三维几何上.当时我们还在想这三维计算几何的正确率有点太高了还在感叹ICPC选手的含金量,直到赛后我才知道这H题的铸币出 ...

  2. 2019-2020 ICPC, Asia Jakarta Regional Contest (Online Mirror, ICPC Rules, Teams Preferred)

    2019-2020 ICPC, Asia Jakarta Regional Contest (Online Mirror, ICPC Rules, Teams Preferred) easy: ACE ...

  3. 2018 ICPC Asia Jakarta Regional Contest

    题目传送门 题号 A B C D E F G H I J K L 状态 Ο . . Ο . . Ø Ø Ø Ø . Ο Ο:当场 Ø:已补 .  :  待补 A. Edit Distance Thin ...

  4. 2019-2020 ICPC, Asia Jakarta Regional Contest

    目录 Contest Info Solutions A. Copying Homework C. Even Path E. Songwriter G. Performance Review H. Tw ...

  5. 2019-2020 ICPC, Asia Jakarta Regional Contest H. Twin Buildings

    As you might already know, space has always been a problem in ICPC Jakarta. To cope with this, ICPC ...

  6. 2018-2019, ICPC, Asia Yokohama Regional Contest 2018 K

    传送门:https://codeforces.com/gym/102082/attachments 题解: 代码: /** * ┏┓ ┏┓ * ┏┛┗━━━━━━━┛┗━━━┓ * ┃ ┃ * ┃ ━ ...

  7. Gym - 101981K The 2018 ICPC Asia Nanjing Regional Contest K.Kangaroo Puzzle 暴力或随机

    题面 题意:给你1个20*20的格子图,有的是障碍有的是怪,你可以每次指定上下左右的方向,然后所有怪都会向那个方向走, 如果2个怪撞上了,就融合在一起,让你给不超过5w步,让所有怪都融合 题解:我们可 ...

  8. Gym - 101981M The 2018 ICPC Asia Nanjing Regional Contest M.Mediocre String Problem Manacher+扩增KMP

    题面 题意:给你2个串(长度1e6),在第一个串里找“s1s2s3”,第二个串里找“s4”,拼接后,是一个回文串,求方案数 题解:知道s1和s4回文,s2和s3回文,所以我们枚举s1的右端点,s1的长 ...

  9. Gym - 101981G The 2018 ICPC Asia Nanjing Regional Contest G.Pyramid 找规律

    题面 题意:数一个n阶三角形中,有多少个全等三角形,n<=1e9 题解:拿到题想找规律,手画开始一直数漏....,最后还是打了个表 (打表就是随便定个点为(0,0),然后(2,0),(4,0), ...

  10. Gym - 101981I The 2018 ICPC Asia Nanjing Regional Contest I.Magic Potion 最大流

    题面 题意:n个英雄,m个怪兽,第i个英雄可以打第i个集合里的一个怪兽,一个怪兽可以在多个集合里,有k瓶药水,每个英雄最多喝一次,可以多打一只怪兽,求最多打多少只 n,m,k<=500 题解:显 ...

随机推荐

  1. GPT-4助力数据分析:提升效率与洞察力的未来关键技术

    摘要 随着大数据时代的到来,数据分析已经成为企业和组织的核心竞争力.然而,传统的数据分析方法往往无法满足日益增长的数据分析需求的数量和复杂性.在这种背景下,ChatGPT-4作为一种先进的自然语言处理 ...

  2. (2023.8.28)Hi铁布衫-CM Ver 0.001 - Cracked-writeup

    Hi铁布衫-CM Ver 0.001 WriteUp 本文作者:XDbgPYG(小吧唧) 发布时间:2023年8月28日 内容概要:Hi铁布衫-CM Ver 0.001 WriteUp 收集信息 有一 ...

  3. 图解Spark Graphx实现顶点关联邻接顶点的函数原理

    一.场景案例 在一张社区网络里,可能需要查询出各个顶点邻接关联的顶点集合,类似查询某个人关系比较近的都有哪些人的场景. 在用Spark graphx中,通过函数collectNeighbors便可以获 ...

  4. Codeforces 1462F The Treasure of The Segments

    题意 给\(n(1\leq n\leq 2*10^5)\)个线段$[l_i,r_i] (1≤l_i≤r_i≤10^9) $,问最少删除几个线段,使得剩下线段中,有至少一个线段与所有线段相交. 分析 对 ...

  5. 在CentOS 8上安装Xrdp远程桌面服务

    如何在CentOS 8上安装Xrdp远程桌面服务 写在前面 Xrdp是Microsoft远程桌面协议(RDP)的开源实现,可让您以图形方式控制远程系统.使用RDP,您可以登录到远程计算机并创建真实的桌 ...

  6. 如何用ppt打印9张一面,并且去除边距?

    如何用ppt打印9张一面,并且去除边距?      方法其实很简单,答主不要在ppt软件的打印选项里设置[每页打印9张幻灯片],而是使用默认的[每页打印1张幻灯片]. 然后去[打印机属性]里设置,我是 ...

  7. MySQL数据库操作 Lab1

              实验一 MySQL数据库操作 实验目的: 掌握MySQL安装.配置与登录方法,使用MySQL客户创建数据库及对数据库表完成各种操作 实验内容: 1. 安装MySQL数据库管理系统, ...

  8. 【Flask模板注入】

    [Flask模板注入]--概览 背景 Flask是python语言下的轻量级web应用框架,可以用来开发一些简单的网站.它使用Jinjia2渲染引擎(将html文件存放在templates文件夹中,当 ...

  9. OTOCI 题解

    OTOCI 题目大意 给定 \(n\) 个带权的点,需要进行四种操作:查询两点连通性:加边:修改点权:查询两点路径的权值和. 思路分析 首先观察题目,我们会发现,在所有的操作结束后,所有的点构成一个森 ...

  10. 【虹科干货】谈谈Redis Enterprise实时搜索的过人之处

    我们都知道,用户在使用应用程序时候,对于速度有着越来越高的要求,真可谓是"一秒也等不及".而开发团队又该怎样来满足这种对于实时性的期望呢? 文章速览: Redis Enterpri ...