【YBT2023寒假Day15 C】缺口一样(数论)(莫队)(根号分治)

news/2024/10/19 16:41:03/

缺口一样

题目链接:YBT2023寒假Day15 C

题目大意

给你一个序列,多次询问,每次问你一个区间这里面所有非空点集的最大公约数之积,对质数取模。

思路

首先质因子之间是独立的,考虑对于每个质数分别计算再乘起来。
那对于一个质数,如果区间 [l,r][l,r][l,r] 有恰好 cic_ici 个是 pip^ipi 的倍数,那 ppp 贡献的次数就相当于对于每个 iii,选 [l,r][l,r][l,r] 一个子集使得所有数 ppp 的次数最小值恰好是 iii 的方案数乘倍数。
那要的是恰好,我们 cic_ici 是倍数,也就是至少 iii 次,那答案就是:(因为是非空子集所以要减一)
∑i⩾1i(2ci−1−(2ci+1−1))\sum\limits_{i\geqslant 1}i(2^{c_i}-1-(2^{c_{i+1}}-1))i1i(2ci1(2ci+11))
=∑i⩾1(2ci−1)=\sum\limits_{i\geqslant 1}(2^{c_i}-1)=i1(2ci1)

那这个 ppp 的贡献就是 p∑i⩾1(2ci−1)p^{\sum\limits_{i\geqslant 1}(2^{c_i}-1)}pi1(2ci1),根据欧拉定理上面的指数可以对 mod−1mod-1mod1 取模。
那一个区间的问题似乎解决了。


那多个区间要怎么多,那我们一是维护每个质数的 cic_ici,而是再维护对应给答案的贡献。
那维护数组这个不难想到莫队。
那每次就是枚举加入或删除那个数的因子 ppp,把 ppp 的贡献改了。
那因子个数 log⁡n\log nlogn,那复杂度就是 nnlog⁡nn\sqrt{n}\log nnnlogn,过不了。
瓶颈显然在每次插入的时候复杂度是 O(log⁡n)O(\log n)O(logn) 的。


考虑到一个事情是 ⩾R\geqslant \sqrt{R}RRRR 是值域)的因子只会有一个,而且题目的值域是跟 nnn 同阶的。
考虑再来个根号分治,对于大因子我们直接像上面的方法暴力统计。
小的个数不超过 R\sqrt{R}R,可以直接预处理出每个前缀每个小质数 ppp 每个 kkk 这个前缀里有多少个数是 pkp^kpk 的倍数。就不需要用根号分治来做,也是 O(nn)O(n\sqrt{n})O(nn) 的。

那么题目最后就是 O(nn)O(n\sqrt{n})O(nn) 解决了。

代码

#include<cmath>
#include<cstdio>
#include<vector>
#include<algorithm>
#define ll long long
#define mo 998244353using namespace std;const int N = 1e5 + 100;
const int K = 405;
int n, m, prime[N], a[N], sum[N][700];
int blo[N], bl[N], br[N], B, bg[N], np[N];
vector <pair <int, int> > id;
struct Quest {int l, r, id;
}q[N];
ll inv[N], now, ans[N];
vector <ll> tim[N], invs[N];void Init() {inv[0] = inv[1] = 1; for (int i = 2; i < N; i++) inv[i] = inv[mo % i] * (mo - mo / i) % mo;for (int i = 2; i < N; i++) {if (!np[i]) {prime[++prime[0]] = i;if (i <= K) {int now = 1, cnt = 0;while (now * i < N) now *= i, id.push_back(make_pair(now, i));}tim[prime[0]].push_back(i);invs[prime[0]].push_back(inv[i]);np[i] = prime[0];}else np[i] = 0;for (int j = 1; j <= prime[0] && i * prime[j] < N; j++) {np[i * prime[j]] = 1; if (i % prime[j] == 0) break;}}
}bool cmp(Quest x, Quest y) {if (blo[x.l] != blo[y.l]) return blo[x.l] < blo[y.l];return x.r < y.r;
}void insert(int now) {for (int i = 1; i <= prime[0] && prime[i] * prime[i] <= now; i++)while (now % prime[i] == 0) {ll tmp = tim[i][tim[i].size() - 1];tim[i].push_back(tmp * tmp % mo);tmp = invs[i][invs[i].size() - 1];invs[i].push_back(tmp * tmp % mo);now /= prime[i];}if (now > 1) {ll tmp = tim[np[now]][tim[np[now]].size() - 1];tim[np[now]].push_back(tmp * tmp % mo);tmp = invs[np[now]][invs[np[now]].size() - 1];invs[np[now]].push_back(tmp * tmp % mo);}
}int num[N];void ins(int x) {if (bg[x] == 1) return ;now = now * tim[np[bg[x]]][num[np[bg[x]]]] % mo;num[np[bg[x]]]++;
} void dec(int x) {if (bg[x] == 1) return ;num[np[bg[x]]]--;now = now * invs[np[bg[x]]][num[np[bg[x]]]] % mo;
}int main() {
//	freopen("C2.in", "r", stdin);
//	freopen("write.txt", "w", stdout);freopen("lhsx2023.in", "r", stdin);freopen("lhsx2023.out", "w", stdout);Init();scanf("%d %d", &n, &m); B = sqrt(n);for (int i = 1; i <= n; i++) {blo[i] = (i - 1) / B + 1;if (!bl[blo[i]]) bl[blo[i]] = i;br[blo[i]] = i;}for (int i = 1; i <= n; i++) {scanf("%d", &a[i]);int now = a[i];for (int j = 1; j <= prime[0] && prime[j] <= K; j++)while (now % prime[j] == 0) now /= prime[j];bg[i] = now;for (int j = 0; j < id.size(); j++)sum[i][j] = sum[i - 1][j] + (a[i] % id[j].first == 0);insert(a[i]);}for (int i = 1; i <= m; i++) {scanf("%d %d", &q[i].l, &q[i].r); q[i].id = i;}sort(q + 1, q + m + 1, cmp);int l = 1, r = 0; now = 1;for (int i = 1; i <= m; i++)  {while (l > q[i].l) l--, ins(l);while (r < q[i].r) r++, ins(r);while (l < q[i].l) dec(l), l++;while (r > q[i].r) dec(r), r--;ans[q[i].id] = now;for (int j = 0; j < id.size(); j++) {int num = sum[r][j] - sum[l - 1][j];(ans[q[i].id] *= tim[np[id[j].second]][num] * inv[id[j].second] % mo) %= mo;}}for (int i = 1; i <= m; i++) printf("%lld\n", ans[i]);return 0;
}

http://www.ppmy.cn/news/27787.html

相关文章

网络协议(八):传输层-TCP(三次握手、四次挥手原理)

网络协议系列文章 网络协议(一)&#xff1a;基本概念、计算机之间的连接方式 网络协议(二)&#xff1a;MAC地址、IP地址、子网掩码、子网和超网 网络协议(三)&#xff1a;路由器原理及数据包传输过程 网络协议(四)&#xff1a;网络分类、ISP、上网方式、公网私网、NAT 网络…

electron sha512 checksum mismatch

sha512 checksum mismatch错误 此错误常常发生在electron检查更新时&#xff0c;导致检查更新失败。 自动更新使用的模块 electron-updater or electron-differential-updater win下electron-builder打包 使用electron-builder打包之后&#xff0c;进行版本增量更新遇到的…

Mybatis-plus 分页集成以及基本使用总结 入门和案例 注解连表查询分页案例等

简介 Mybaits-plus 是mybits 的升级版&#xff0c;从mybaits 升级到mybaits-plus 可以实现平滑升级 Mybaits-plus 本身提供了大量的基本查询方法以及强大的 Wrapper(包装) 类 用于查询的 QueryWrapper 以及 更新的 UpdateWrapper &#xff0c;使用Wrapper 基本已经可以构建大…

duilib.dll丢失怎么办?dll文件丢失修复方法分享

duilib.dll丢失怎么办&#xff1f;其实在使用 Windows 系统的过程中&#xff0c;有时会出现提示“duilib.dll丢失”的错误。这个错误可能会影响电脑的正常运行&#xff0c;但是不用担心&#xff0c;今天小编来给大家详细的讲解一下duilib.dll丢失都有哪些解决方法。 一.什么是…

【人工智能 AI】怎样实施RPA 机器人流程自动化(Robotic Process Automation)?核心技术有哪些?

文章目录 RPA 简介RPA的实施RPA的核心技术1. 自动化测试(1)自动化测试工具(2)自动化测试框架2. 自动化脚本(1)自动化脚本语言(2)自动化脚本框架3. 机器学习(1)机器学习模型(2)机器学习框架(3)自然语言处理(4)图像处理(5)深度学习(6)机器人操作系统RPA核心能…

协作对象死锁及其解决方案

协作对象死锁及其解决方案 1.前言 在遇到转账等的需要保证线程安全的情况时&#xff0c;我们通常会使用加锁的方式来保证线程安全&#xff0c;但如果无法合理的使用锁&#xff0c;很可能导致死锁。或者有时我们使用线程池来进行资源的使用&#xff0c;如调用数据库&#xff0…

在vue项目中使用video.js实现视频播放和视频进度条打点

一、用video.js实现视频播放 1、安装video.js插件 // 安装video.js插件 npm install video.js -S // 如果需要播放rtmp直播流&#xff0c;需安装一下插件 npm install videojs-flash -S 2、在组件代码里使用 <template><div data-vjs-player><video ref&quo…

释放内存流程

你好&#xff0c;我是安然无虞。 thread cache回收内存 当从 thread cache 中申请的内存对象使用完毕需要还回来的时候, 只需要计算出该内存对象对应 thread cache 中的哪一个自由链表桶, 然后将该内存对象插入进去即可. 不过需要注意的是, 如果不断有内存对象释放回来, 那么…