思路来源: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}}\)。

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;

const int N = 1E5 + 10, Mod = 998244353, M = 105;
int euler[M], cntp, primes[M], state[M];
int a[N];
int cnt[M][30];
bitset<30> st[M]; struct SegMentTree {
int l, r;
LL sum;
LL laz;
bitset<30> has;
}tr[N * 4]; void get_euler(int n) {
euler[1] = 1;
for (int i = 2; i <= n; i++) {
if (!state[i]) primes[cntp++] = i, euler[i] = i - 1;
for (int j = 0; primes[j] <= n / i; j++) {
state[i * primes[j]] = true;
if (i % primes[j] == 0) {
euler[i * primes[j]] = euler[i] * primes[j];
break;
}
euler[i * primes[j]] = euler[i] * (primes[j] - 1);
}
}
} LL qmi(LL a, LL b, LL Mod) {
LL res = 1ll;
while (b) {
if (b & 1) res = res * a % Mod;
b >>= 1;
a = a * a % Mod;
}
return res % Mod;
} void pushup(int u) {
tr[u].sum = (tr[u << 1].sum + tr[u << 1 | 1].sum) % Mod;
tr[u].has = tr[u << 1].has & tr[u << 1 | 1].has;
} void pushdown(int u) {
auto &root = tr[u], &left = tr[u << 1], &right = tr[u << 1 | 1];
if (root.laz == 1) return;
left.sum = left.sum * root.laz % Mod;
right.sum = right.sum * root.laz % Mod;
left.laz = left.laz * root.laz % Mod;
right.laz = right.laz * root.laz % Mod;
root.laz = 1;
} void build(int u, int l, int r) {
if (l == r) {
tr[u] = {l, r, euler[a[l]], 1ll, st[a[l]]};
return;
}
tr[u] = {l, r}, tr[u].laz = 1ll;
int mid = l + r >> 1;
build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
pushup(u);
} void modify(int u, int l, int r, int k, int ct) {
int p = primes[k];
if (tr[u].l >= l && tr[u].r <= r && tr[u].has[k]) { //当前区间有这个质因子
tr[u].sum = tr[u].sum * qmi(p, ct, Mod) % Mod;
tr[u].laz = tr[u].laz * qmi(p, ct, Mod) % Mod;
} else if (tr[u].l == tr[u].r) { //直至单点修改
tr[u].has[k] = 1;
tr[u].sum = tr[u].sum * (p - 1) % Mod;
tr[u].sum = tr[u].sum * qmi(p, ct - 1, Mod) % Mod;
} else {
pushdown(u);
int mid = tr[u].l + tr[u].r >> 1;
if (l <= mid) modify(u << 1, l, r, k, ct);
if (r > mid) modify(u << 1 | 1, l, r, k, ct);
pushup(u);
}
} LL query(int u, int l, int r) {
if (tr[u].l >= l && tr[u].r <= r) {
return tr[u].sum;
} else {
pushdown(u);
int mid = tr[u].l + tr[u].r >> 1;
LL res = 0;
if (l <= mid) res = (res + query(u << 1, l, r)) % Mod;
if (r > mid) res = (res + query(u << 1 | 1, l, r)) % Mod;
return res;
}
} int main() {
get_euler(100);
for (int i = 1; i <= 100; i++) {
for (int j = 0; j < cntp; j++) {
if (i % primes[j] == 0) {
int s = 0, temp = i;
while (temp % primes[j] == 0) s++, temp /= primes[j];
cnt[i][j] = s;
st[i][j] = (cnt[i][j] > 0);
}
}
}
int n, m;
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
} build (1, 1, n); while (m--) {
int op, l, r;
scanf("%d%d%d", &op, &l, &r);
if (op == 0) {
int w;
scanf("%d", &w);
for (int i = 0; i < cntp; i++) {
if (cnt[w][i]) {
modify(1, l, r, i, cnt[w][i]);
}
}
} else {
printf("%lld\n", query(1, l, r));
}
} return 0;
}

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. Unity UGUI的PhysicsRaycaster (物理射线检测)组件的介绍及使用

    Unity UGUI的PhysicsRaycaster (物理射线检测)组件的介绍及使用 1. 什么是PhysicsRaycaster组件? PhysicsRaycaster是Unity UGUI中的 ...

  2. Power AutoMate: 运行脚本程序

    运行脚本文件 操作步骤 配置脚本 点击脚本文件菜单,选中运行python脚本.在其中输入需要徐行的脚本点击保存 之后界面会如下所示: 运行程式 可以看到程式正常运行

  3. rpm安装21c单实例数据库

    linux 7.6 使用rpm安装21c单实例数据库 一.基础环境配置 1.1 关闭防火墙 systemctl stop firewalld systemctl disable firewalld s ...

  4. 知识图谱(Knowledge Graph)- Neo4j 5.10.0 使用 - CQL - 太极拳传承谱系表

    删除数据库中以往的图 MATCH (n) DETACH DELETE n 创建节点 CREATE命令语法 Neo4j CQL"CREATE"命令用于创建没有属性的节点. 它只是创建 ...

  5. Docker容器怎么安装Vim编辑器

    ​ 在现代软件开发和系统管理中,Docker已经成为一个不可或缺的工具.它允许我们轻松地创建.部署和运行应用程序,以及构建可移植的容器化环境.然而,在Docker容器中安装特定的工具可能会有一些挑战, ...

  6. Linux 网络发包流程

    哈喽大家好,我是咸鱼 之前咸鱼在<Linux 网络收包流程>一文中介绍了 Linux 是如何实现网络接收数据包的 简单回顾一下: 数据到达网卡之后,网卡通过 DMA 将数据放到内存分配好的 ...

  7. java与es8实战之二:实战前的准备工作

    欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 本篇是<java与es8实战>系 ...

  8. Python API接口对接详解与实践

    ​ 在数字化时代,数据交互已经成为各种应用的必备功能.API(应用程序编程接口)就是实现不同应用程序之间数据交互的一种方式.Python作为一种功能强大的编程语言,也提供了许多用于对接API的库和框架 ...

  9. C++ 算法竞赛、02 周赛篇 | AcWing 第2场周赛

    AcWing 第2场周赛 竞赛 - AcWing 3626 三元一次方程 AcWing 3626. 三元一次方程 - AcWing 两层循环 #include <iostream> usi ...

  10. EXE一机一码打包加密大师1.4.0更新-支持导出注册机

    EXE一机一码打包加密大师可以对EXE文件进行加密处理,可以让EXE支持一机一码功能,也可以支持静态打开密码功能, 方便开发人员想用户收费. 详细软件使用说明可以查看下面的说明文档: EXE一机一码打 ...