P4681 [THUSC 2015] 平方运算 Solution

Description

给定序列 a = ( a 1 , a 2 , ⋯ , a n ) a=(a_1,a_2,\cdots,a_n) a=(a1,a2,,an) 和常数 p p p ,有 m m m 个操作,分以下两种:

  • modify ⁡ ( l , r ) \operatorname{modify}(l,r) modify(l,r):对每个 i ∈ [ l , r ] i \in [l,r] i[l,r] 执行 a i ← a i 2 m o d p a_i \leftarrow a_i^2 \bmod p aiai2modp.
  • query ⁡ ( l , r ) \operatorname{query}(l,r) query(l,r):求 ∑ i = l r a i \sum\limits_{i=l}^r a_i i=lrai.

Limitations

1 ≤ n , m ≤ 1 0 5 1 \le n,m \le 10^5 1n,m105
0 ≤ a i < p \textcolor{red}{0} \le a_i < p 0ai<p
p ∈ { 233 , 2332 , 5 , 8192 , 23 , 45 , 37 , 4185 , 5850 , 2975 , 2542 , 2015 , 2003 , 2010 , 4593 , 4562 , 1034 , 5831 , 9905 , 9977 } p \in {\{233,2332,5,8192,23,45,37,4185,5850,2975,2542,2015,2003,2010,4593,4562,1034,5831,9905,9977\}} p{233,2332,5,8192,23,45,37,4185,5850,2975,2542,2015,2003,2010,4593,4562,1034,5831,9905,9977}
2 s , 250 MB 2\text{s},250\text{MB} 2s,250MB

Solution

modify ⁡ \operatorname{modify} modify 操作不能直接标记,也不能直接暴力改.
但是模意义下的平方运算显然是有周期性的,打表发现,在 p p p 取给定数时,所有数的周期的 lcm ⁡ \operatorname{lcm} lcm 不大于 60 60 60,并且每个数平方不超过 11 11 11 次就会进入循环节.
考虑在线段树上维护:

  • c y c l e cycle cycle:这个区间内的数是否全部进入循环节.
  • s u m i sum_i sumi:全部进入循环节的情况下,每个数平方 i i i 次后的和.
  • n o w now now:当前区间的和在循环节的第几个位置.
  • t a g tag tag:标记,表示儿子需要平方几次.

特别地,如果没有全部进入循环节,则用 s u m 0 sum_0 sum0 来记录和.
然后进入循环节的直接跳,没有的就暴力改(因为不超过 11 11 11 次).
注意当一个数进入循环节时,需要将 s u m i sum_i sumi 全部算出.
剩下就没什么了,一开始时把每个数平方的周期长度全算一遍即可.

Code

4.27 KB , 9.45 s , 193.55 MB (in total, C++ 20 with O2) 4.27\text{KB},9.45\text{s},193.55\text{MB}\;\texttt{(in total, C++ 20 with O2)} 4.27KB,9.45s,193.55MB(in total, C++ 20 with O2)

// Problem: P4681 [THUSC 2015] 平方运算
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P4681
// Memory Limit: 250 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)#include <bits/stdc++.h>
using namespace std;using i64 = long long;
using ui64 = unsigned long long;
using i128 = __int128;
using ui128 = unsigned __int128;
using f4 = float;
using f8 = double;
using f16 = long double;template<class T>
bool chmax(T &a, const T &b){if(a < b){ a = b; return true; }return false;
}template<class T>
bool chmin(T &a, const T &b){if(a > b){ a = b; return true; }return false;
}struct Node {int l, r;bool cycle;int now, tag;array<i64, 60> sum;
};
inline int ls(int u) { return 2 * u + 1; }
inline int rs(int u) { return 2 * u + 2; }struct SegTree {vector<Node> tr;vector<int> P, vis;int M, mod;inline SegTree() {}inline SegTree(const vector<int>& a, int _mod):P(_mod), vis(_mod, -1), M(1), mod(_mod) {for (int i = 0; i < mod; i++) get_loop(i);for (int i = 0; i < mod; i++)if (P[i] != 0) M = lcm(M, P[i]);const int n = a.size();tr.resize(n << 2);build(0, 0, n - 1, a);}inline void get_loop(int x) {for (int i = 0, y = x; ; i++, y = y * y % mod) {if (vis[y] != -1) {P[y] = i - vis[y];break;}else vis[y] = i;}for (int y = x; vis[y] != -1; y = y * y % mod) vis[y] = -1;}inline void upd(int u) {if (P[tr[u].sum[0]] != 0) {for (int i = 1; i < M; i++) tr[u].sum[i] = tr[u].sum[i - 1] * tr[u].sum[i - 1] % mod;tr[u].now = 0;tr[u].cycle = 1;}else tr[u].now = tr[u].cycle = 0;}inline void apply(int u, int k) {tr[u].tag = (tr[u].tag + k) % M;tr[u].now = (tr[u].now + k) % M;}inline void pushup(int u) {tr[u].cycle = tr[ls(u)].cycle && tr[rs(u)].cycle;tr[u].now = 0;if (!tr[u].cycle)tr[u].sum[0] = tr[ls(u)].sum[tr[ls(u)].now] + tr[rs(u)].sum[tr[rs(u)].now];else {int nowL = tr[ls(u)].now, nowR = tr[rs(u)].now;for (int i = 0; i < M; i++) {tr[u].sum[i] = tr[ls(u)].sum[nowL] + tr[rs(u)].sum[nowR];nowL = (nowL + 1) % M;nowR = (nowR + 1) % M;}}}inline void pushdown(int u) {if (tr[u].tag) {apply(ls(u), tr[u].tag);apply(rs(u), tr[u].tag);tr[u].tag = 0;}}inline void build(int u, int l, int r, const vector<int>& a) {tr[u].l = l;tr[u].r = r;if (l == r) {tr[u].sum[0] = a[l];tr[u].tag = 0;return upd(u);}const int mid = (l + r) >> 1;build(ls(u), l, mid, a);build(rs(u), mid + 1, r, a);pushup(u);}inline void square(int u, int l, int r) {if (l <= tr[u].l && tr[u].r <= r && tr[u].cycle) return apply(u, 1);if (tr[u].l == tr[u].r) {tr[u].sum[0] = tr[u].sum[0] * tr[u].sum[0] % mod;return upd(u);}const int mid = (tr[u].l + tr[u].r) >> 1;pushdown(u);if (l <= mid) square(ls(u), l, r);if (r > mid) square(rs(u), l, r);pushup(u);}inline i64 query(int u, int l, int r) {if (l <= tr[u].l && tr[u].r <= r) return tr[u].sum[tr[u].now];const int mid = (tr[u].l + tr[u].r) >> 1;i64 res = 0;pushdown(u);if (l <= mid) res += query(ls(u), l, r);if (r > mid) res += query(rs(u), l, r);return res;}
};signed main() {ios::sync_with_stdio(0);cin.tie(0), cout.tie(0);int n, m, p;scanf("%d %d %d", &n, &m, &p);vector<int> a(n);for (int i = 0; i < n; i++) scanf("%d", &a[i]);SegTree seg(a, p);for (int i = 0, op, l, r; i < m; i++) {scanf("%d %d %d", &op, &l, &r);l--, r--;if (op == 1) seg.square(0, l, r);else printf("%lld\n", seg.query(0, l, r));}return 0;
}

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

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

相关文章

刷题记录 贪心算法-2:455. 分发饼干

题目&#xff1a;455. 分发饼干 难度&#xff1a;简单 假设你是一位很棒的家长&#xff0c;想要给你的孩子们一些小饼干。但是&#xff0c;每个孩子最多只能给一块饼干。 对每个孩子 i&#xff0c;都有一个胃口值 g[i]&#xff0c;这是能让孩子们满足胃口的饼干的最小尺寸&a…

Flutter_学习记录_导航和其他

Flutter 的导航页面跳转&#xff0c;是通过组件Navigator 和 组件MaterialPageRoute来实现的&#xff0c;Navigator提供了很多个方法&#xff0c;但是目前&#xff0c;我只记录我学习过程中接触到的方法&#xff1a; Navigator.push(), 跳转下一个页面Navigator.pop(), 返回上一…

基于 AWS SageMaker 对 DeepSeek-R1-Distilled-Llama-8B 模型的精调与实践

在当今人工智能蓬勃发展的时代&#xff0c;语言模型的性能优化和定制化成为研究与应用的关键方向。本文聚焦于 AWS SageMaker 平台上对 DeepSeek-R1-Distilled-Llama-8B 模型的精调实践&#xff0c;详细探讨这一过程中的技术细节、操作步骤以及实践价值。 一、实验背景与目标 …

arkui-x跨平台与android java联合开发

华为鸿蒙系统采用的是arkts&#xff0c;支持跨平台crossplatform 即前端为arkts&#xff0c;arkui-x框架&#xff0c;后端为其他的语言框架。 本篇示例后端采用的是java&#xff0c;android studio工程。 主要方式是前端鸿蒙完成界面元素、布局等效果&#xff0c;后面androi…

机器人基础深度学习基础

参考&#xff1a; &#xff08;1&#xff09;【具身抓取课程-1】机器人基础 &#xff08;2&#xff09;【具身抓取课程-2】深度学习基础 1 机器人基础 从平面二连杆理解机器人学 正运动学&#xff1a;从关节角度到末端执行器位置的一个映射 逆运动学&#xff1a;已知末端位置…

C#面试常考随笔4:int? 和 int的区别,以及int?的运用场景?

可空性 int?&#xff1a;它是int的可空类型&#xff0c;允许将null赋值给该变量。int?实际上是Nullable<int>的缩写形式&#xff0c;是一个可以为null的整数类型。例如&#xff1a;int? num2 null;或者int? num3 10;都是合法的。 内存分配与存储 int?&#xff…

k8s支持自定义field-selector spec.hostNetwork过滤

好久没写博客啦&#xff0c;年前写一个博客就算混过去啦&#x1f602; 写一个小功能&#xff0c;对于 Pod&#xff0c;在没有 label 的情况下&#xff0c;支持 --field-selector spec.hostNetwork 查询 Pod 是否为 hostNetwork 类型&#xff0c;只为了熟悉 APIServer 是如何构…

VScode使用笔记

VScode打开keil工程的配置 [STM32]从零开始的vs code 连接keil教程_vscode配置keil环境-CSDN博客 补充&#xff1a;包含头文件 vscode编辑keil arm工程中遇到的问题以及解决方法 - 了不起的亮亮 - 博客园

5分钟带你获取deepseek api并搭建简易问答应用

目录 1、获取api 2、获取base_url和chat_model 3、配置模型参数 方法一&#xff1a;终端中临时将加入 方法二&#xff1a;创建.env文件 4、 配置client 5、利用deepseek大模型实现简易问答 deepseek-v3是截止博文撰写之日&#xff0c;无论是国内还是国际上发布的大模型中…

RDMA 工作原理 | 支持 RDMA 的网络协议

注&#xff1a;本文为 “RDMA” 相关文章合辑。 英文引文机翻未校。 图片清晰度受引文所限。 Introduction to Remote Direct Memory Access (RDMA) Written by: Dotan Barak on March 31, 2014.on February 13, 2015. What is RDMA? 什么是 RDMA&#xff1f; Direct me…

【AutoSar】汽车诊断标准协议UDS详解

目录 一、基本概念二、UDS诊断协议2.1 诊断服务的概念2.2常用的诊断服务2.2.1 诊断会话控制服务&#xff08;10服务&#xff09;2.2.2 会话访问0x27服务2.2.3 用于读写的DID的0x22/0x2E服务 一、基本概念 车辆的诊断需要有Tester端和ECU段通过应答的方式进行通信&#xff0c;他…

wx043基于springboot+vue+uniapp的智慧物流小程序

开发语言&#xff1a;Java框架&#xff1a;springbootuniappJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#…

实践网络安全:常见威胁与应对策略详解

&#x1f4dd;个人主页&#x1f339;&#xff1a;一ge科研小菜鸡-CSDN博客 &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; 引言 在数字化转型的浪潮中&#xff0c;网络安全的重要性已达到前所未有的高度。无论是个人用户、企业&#xff0c;还是政府机构…

深入 Rollup:从入门到精通(三)Rollup CLI命令行实战

准备阶段&#xff1a;初始化项目 初始化项目&#xff0c;这里使用的是pnpm&#xff0c;也可以使用yarn或者npm # npm npm init -y # yarn yarn init -y # pnpm pnpm init安装rollup # npm npm install rollup -D # yarn yarn add rollup -D # pnpm pnpm install rollup -D在…

快速分析LabVIEW主要特征进行判断

在LabVIEW中&#xff0c;快速分析程序特征进行判断是提升开发效率和减少调试时间的重要技巧。本文将介绍如何高效地识别和分析程序的关键特征&#xff0c;从而帮助开发者在编写和优化程序时做出及时的判断&#xff0c;避免不必要的错误。 ​ 数据流和并行性分析 LabVIEW的图形…

如何运用python爬虫爬取知网相关内容信息?

爬取知网内容的详细过程 爬取知网内容需要考虑多个因素&#xff0c;包括网站的结构、反爬虫机制等。以下是一个详细的步骤和代码实现&#xff0c;帮助你使用Python爬取知网上的论文信息。 1. 数据准备 首先&#xff0c;需要准备一些基础数据&#xff0c;如知网的URL、请求头…

【AI】【本地部署】OpenWebUI的升级并移植旧有用户信息

【背景】 OpenWebUI的版本升级频率很高&#xff0c;并会修改旧版本的Bug&#xff0c;不过对于已经在使用的系统&#xff0c;升级后现有用户信息都会丢失&#xff0c;于是研究如何在升级后将现有的用户信息移植到升级后版本。 【准备工作】 OpenWebUI的升级步骤在Docker中有现…

【阅读笔记】New Edge Diected Interpolation,NEDI算法,待续

一、概述 由Li等提出的新的边缘指导插值(New Edge—Di-ected Interpolation&#xff0c;NEDI)算法是一种具有良好边缘保持效果的新算法&#xff0c;它利用低分辨率图像与高分辨率图像的局部协方差问的几何对偶性来对高分辨率图像进行自适应插值。 2001年Xin Li和M.T. Orchard…

Ruby Dir 类和方法详解

Ruby Dir 类和方法详解 引言 在 Ruby 中&#xff0c;Dir 是一个非常有用的类&#xff0c;用于处理文件系统中的目录。它提供了许多方便的方法来列出目录内容、搜索文件、以及处理文件系统的其他相关操作。本文将详细介绍 Ruby 的 Dir 类及其常用方法。 一、Dir 类概述 Dir …

MySQL 基础学习(1):数据类型与操作数据库和数据表

MySQL 基础学习&#xff1a;数据类型与操作数据库和数据表 在这篇博客中&#xff0c;我们将深入学习 MySQL 的基础操作&#xff0c;重点关注数据库和数据表的操作&#xff0c;以及 MySQL 中常见的数据类型。希望本文能帮助你更好地理解和掌握 MySQL 的基本用法。 一、操作数据…