The Child and Sequence 题解

news/2025/1/22 19:06:23/文章来源:https://www.cnblogs.com/cz2010124/p/18686619

题目链接

题目描述

有一个长度为 \(n\) 的数列 \(\{a_n\}\)\(m\) 次操作,操作内容如下:

  1. 格式为 1 l r,表示求 \(\sum \limits _{i=l}^{r} a_i\) 的值并输出。
  2. 格式为 2 l r x,表示对区间 \([l,r]\) 内每个数取模,模数为 \(x\)
  3. 格式为 3 k x,表示将 \(a_k\) 修改为 \(x\)

\(1 \leq n, m \leq 10^5\)\(1 \leq l, r, k, x, a_i \leq 10^9\)


解题思路

通过题目中两个区间操作不难发现此题需要用 线段树 维护, 本题解着重讲解操作 \(2\)

  • 对于操作 \(1\) :线段树可以轻松维护区间和的查询和维护。

  • 对于操作 \(3\) :线段树也支持单点修改。

    • 对于操作 \(1\) 和操作 \(3\) ,可以先利用线段树做出 P3374 【模板】树状数组 1 这题,如果实在做不出来 那你线段树学了个啥 可以去参考一下题解 。
  • 对于操作 \(2\) :我们可以探究一下 正整数 之间取模的性质:

    • 我们设 \(p\) 为模数, \(x\) 为被模数,关于 \(x\ \text{mod}\ p\) 的值有以下几点性质:

      • 性质 \(1\) :当 \(x < p\) 时:\(x\ \text{mod}\ p = x\)
      • 性质 \(2\) :当 \(x \geq p\) 时: \(x\ \text{mod}\ p < \dfrac{x}{2}\)

      所以对于性质 \(1\) 我们发现所有小于模数 \(p\) 的被模数 \(x\) 对答案没有影响,所以我们可以用线段树维护一个区间 \(max\) ,如果区间 \(max\) 大于模数 \(p\) 我们可以选择不修改。对于性质 \(2\) ,每次取模都会使 \(x\) 至少缩减 \(\frac{1}{2}\) ,所以至多修改 \(\log_2 x\) 次,所以对于区间的修改我们以选择暴力的对区间中的每个节点修改。

    • 对于性质 \(2\) ,我们给出证明:

      \(x = kp + c\) ,(\(c\) 表示 \(x\ \text{mod}\ p\) 的值,\(p\) 为模数, \(kp\) 表示小于等于 \(x\) 可以被 \(p\) 整除的最大正整数)

      根据取模性质得出 \(c < p\) ,又因为 \(p \in \text{N}^* , kp \in \text{N}^*\) ,所以 \(k \in \text{N}^*\) ,所以 \(k \geq 1\)

      然后我们就得出以下式子:

\[c < kp\\ c + c < kp + c\\ 2c < kp + c\\ 2c < x\\ c < \frac{x}{2}\\ x\ \text{mod}\ p < \frac{x}{2}(x\geq p) \]


代码:

#include <bits/stdc++.h>const int N = 100010;int n, m;
long long a[N];class SegmentTree {
public:void pushup(int p) {t[p].sum = t[p << 1].sum + t[(p << 1) + 1].sum;t[p].max = std::max(t[p << 1].max, t[(p << 1) + 1].max);}void build(int p, int l, int r) {t[p].l = l;t[p].r = r;if (l == r) {t[p].sum = a[l];t[p].max = a[l];return;}int mid = (t[p].l + t[p].r) >> 1;build(p << 1, l, mid);build((p << 1) + 1, mid + 1, r);pushup(p);}void change_cover(int p, int x, long long k) {if (t[p].l == t[p].r) {t[p].sum = k;t[p].max = k;return;}int mid = (t[p].l + t[p].r) >> 1;if (x <= mid) change_cover(p << 1, x, k);else change_cover((p << 1) + 1, x, k);pushup(p);}void change_mod(int p, int l, int r, long long k) {if (t[p].max < k) return;if (t[p].l == t[p].r) {t[p].sum %= k;t[p].max %= k;return;}int mid = (t[p].l + t[p].r) >> 1;if (l <= mid) change_mod(p << 1, l, r, k);if (r > mid) change_mod((p << 1) + 1, l, r, k);pushup(p);}long long ask(int p, int l, int r) {if (l <= t[p].l && r >= t[p].r)return t[p].sum;long long sum = 0;int mid = (t[p].l + t[p].r) >> 1;if (l <= mid) sum += ask(p << 1, l, r);if (r > mid) sum += ask((p << 1) + 1, l, r);return sum;}
private:struct point {int l, r;long long sum, max;} t[N << 2];
} t;int main() {scanf("%d%d", &n, &m);for (int i = 1; i <= n; i++)scanf("%lld", &a[i]);t.build(1, 1, n);while (m--) {int op;scanf("%d", &op);if (op == 1) {int l, r;scanf("%d%d", &l, &r);printf("%lld\n", t.ask(1, l, r));} else if (op == 2) {long long k;int l, r;scanf("%d%d%lld", &l, &r, &k);t.change_mod(1, l, r, k);} else {int k;long long x;scanf("%d%lld", &k, &x);t.change_cover(1, k, x);}}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/873386.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

中考英语优秀范文-016 How to keep a good relationship with parents 如何与父母保持良好的关系

1 写作要求 某英文报社正就青少年与父母关系这一话题开展题为“How to keep a good relationship with parents”的征文活动。请你根据以下要点, 写一篇80个词左右的英语短文参加此次活动: 1 父母规矩太多, 过于强调学习成绩, 不理解自己等问题; 2 你对这些问题的看法; 3 你与父…

KubeSphere 开源社区 2024 年度回顾与致谢

随着 2024 年圆满落幕,我们回顾 KubeSphere 社区这一年走过的每一步,感慨万千。2024 年,KubeSphere 继续领跑云原生技术的创新与发展,推动开源文化的传播,致力于为全球开发者和企业用户提供更强大的平台和解决方案。感谢每一位社区成员的辛勤付出,正是因为你们的共同努力…

云--什么是云

https://whatiscloud.com/

城市生命线安全保障:技术应用与策略创新

城市生命线工程是维系城市正常运行、满足群众生产生活需要的重要基础设施。随着城市化进程的加快,城市基础设施生命线安全运行的复杂性日益加剧,保障城市居民日常生活正常运行的水、电、气、热等各类地下管线以及桥梁、市政设施、轨道交通等城市基础设施的安全问题日益突出。…

Android图形层垂直同步虚拟VSYNC机制

简介 某次调图形性能的时候(启动后台录屏,下(或)称case)发现Android SurfaceFlinger Vsync机制并没有以前想的这么简单粗糙,特别是这次调图形性能发现一些跟Vsync有关联,因此做个总结详解。 跟不上旋律节奏的VSYNC 一份追踪报告,发现Vsync信号非常不规律,于是从这里入手…

[日志] 打印异常堆栈信息的技巧

序Java的异常堆栈信息,对提升排查问题的效率,有极大的帮助————便于我们快速定位异常的发生过程和发生异常的代码行。本文使用的日志框架slf4j : 1.7.25 log4j(2) : 2.20.0 日志行的打印策略 : log4j2.properties# property.log.layout.consolePattern=%d{yyyy/MM/dd HH:m…

【vjudge训练记录】大一寒假专项训练——前缀和/差分

训练情况A题 前缀和模板题,我们输入完 \(a_i\) 后直接求前缀和 \(a_i = a_i + a_{i-1}\),求区间 \([l,r]\) 的和就为 \(a_r-a_{l-1}\)点击查看代码 #include <bits/stdc++.h> #define int long long #define endl \nusing namespace std;void solve(){int n,m;cin>&…

VSCode使用之go语言配置

时间:2025/1/22 扩展:go 目的:支持go语言,方便安装其他必备插件安装该扩展包后可以执行该扩展包提供的命令Go:Install/Update Tools来进一步扩展go工具执行命令的窗口可以通过Ctrol+Shift+P调出点击后会出现很多选项,可以根据自己需要勾选然后点击确定,等待下载安装,一般情…

VSCode设置之默认在当前文件目录下打开终端

在vscode界面依次点击“文件”→“首选项”→“设置”→“用户”→“功能”→“终端”,找到Integrated:Cwd选项,将其值修改为”${fileDirname}“,即可在所有打开的工程内实现终端默认在当前文件的路径启动

树上的轮廓线DP!——AGC017F Zigzag

树上的轮廓线DP!——AGC017F Zigzag 注意到 \(n,m\le 20\),考虑状压,设 \(f_{i,S}\) 表示对于第 \(i\) 条线,其路线为 \(S\) 的方案数。 转移需要枚举 \(f_{i-1,S}\) 复杂度 \(\mathcal O(4^n\text{poly}(n))\)。 发现这种相邻状态之间的限制很像矩形中行的扩展,于是我们可…

使用 CSS flex(横向) 实现瀑布流布局(需要后端配合数据分左右)

核心代码(提供思路)<up-waterfall v-model="flowList"><template v-slot:left="{leftList}"><view v-for="(item, index) in leftList" :key="index"><!-- 这里编写您的内容,item为您传递给v-model的数组元素…