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 ai←ai2modp.
- query ( l , r ) \operatorname{query}(l,r) query(l,r):求 ∑ i = l r a i \sum\limits_{i=l}^r a_i i=l∑rai.
Limitations
1 ≤ n , m ≤ 1 0 5 1 \le n,m \le 10^5 1≤n,m≤105
0 ≤ a i < p \textcolor{red}{0} \le a_i < p 0≤ai<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;
}
相关文章:
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 ∈ [ …...
【apt源】RK3588 平台ubuntu20.04更换apt源
RK3588芯片使用的是aarch64架构,因此在Ubuntu 20.04上更换apt源时需要使用针对aarch64架构的源地址。以下是针对RK3588芯片在Ubuntu 20.04上更换apt源到清华源的正确步骤: 步骤一:打开终端 在Ubuntu 20.04中,按下Ctrl Alt T打…...
Angular 2 表单深度解析
Angular 2 表单深度解析 引言 Angular 2作为现代前端开发的框架之一,以其灵活性和强大的功能赢得了众多开发者的青睐。在Angular 2中,表单处理是其中一个重要且复杂的部分。本文将深入解析Angular 2的表单,从基础知识到高级应用,旨在帮助开发者更好地理解和运用Angular 2…...
PHP 7 新特性
PHP 7 新特性 引言 PHP 作为一种广泛使用的服务器端脚本语言,自1995年诞生以来,已经经历了多个版本的迭代。PHP 7 是 PHP 的发展历程中的一个重要里程碑,它带来了许多新特性和改进,旨在提高性能、增强安全性和简化开发过程。本文将详细介绍 PHP 7 的新特性,帮助开发者更…...

vim如何解决‘’文件非法关闭后,遗留交换文件‘’的问题
过程描述: 由于我修改文件时(一定得修改了文件,不做任何修改不会产生这个问题)的非法关闭,比如直接关闭虚拟机,或者直接断开远程工具的远程连接,产生了以下遗留交换文件的问题: 点击…...
【练习】树形dp
G. Group Homework time limit per test: 3 s memory limit per test: 512 MB input: standard input output: standard output No, we don’t want group homework. It’s the place where KaTeX parse error: Expected EOF, got & at position 7: 1 1 &̲lt; 1 …...

Mybatis是如何进行分页的?
大家好,我是锋哥。今天分享关于【Mybatis是如何进行分页的?】面试题。希望对大家有帮助; Mybatis是如何进行分页的? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 MyBatis 实现分页的方式有很多种,最常见…...
【新春特辑】2025年春节技术展望:蛇年里的科技创新与趋势预测
🔥【新春特辑】2025年春节技术展望:蛇年里的科技创新与趋势预测 📅 发布日期:2025年01月29日(大年初一) 在这个辞旧迎新的美好时刻,我们迎来了充满希望的2025年,也是十二生肖中的蛇…...

论文笔记(六十三)Understanding Diffusion Models: A Unified Perspective(五)
Understanding Diffusion Models: A Unified Perspective(五) 文章概括基于得分的生成模型(Score-based Generative Models) 文章概括 引用: article{luo2022understanding,title{Understanding diffusion models: A…...

C++并发:C++内存模型和原子操作
C11引入了新的线程感知内存模型。内存模型精确定义了基础构建单元应当如何被运转。 1 内存模型基础 内存模型牵涉两个方面:基本结构和并发。 基本结构关系到整个程序在内存中的布局。 1.1 对象和内存区域 C的数据包括: 内建基本类型:int&…...

JavaScript函数中this的指向
总结:谁调用我,我就指向谁(es6箭头函数不算) 一、ES6之前 每一个函数内部都有一个关键字是 this ,可以直接使用 重点: 函数内部的 this 只和函数的调用方式有关系,和函数的定义方式没有关系 …...
【java学习笔记】@Autowired注解 使用方法和作用 | 配合@Component注解使用 | IOC控制反转
原本在类中,要用什么对象,就直接new一个对象。这种原始的方式 是由应用本身去控制实例的。 用了Autowired注解后,就相当于把实例(对象)的控制权 交给外部容器来统一管理(降低耦合)。(…...
数论问题76一一容斥原理
容斥原理是一种计数方法,用于计算多个集合的并集中元素的个数,以避免重复计算。以下是其基本内容及相关公式: 两个集合的容斥原理 若有集合A和集合B,那么A与B的并集中元素的个数等于A集合元素个数加上B集合元素个数,再…...

python-leetcode-从中序与后序遍历序列构造二叉树
106. 从中序与后序遍历序列构造二叉树 - 力扣(LeetCode) # Definition for a binary tree node. # class TreeNode: # def __init__(self, val0, leftNone, rightNone): # self.val val # self.left left # self.right r…...

【Oracle篇】使用Hint对优化器的执行计划进行干预(含单表、多表、查询块、声明四大类Hint干预)
💫《博主介绍》:✨又是一天没白过,我是奈斯,从事IT领域✨ 💫《擅长领域》:✌️擅长阿里云AnalyticDB for MySQL(分布式数据仓库)、Oracle、MySQL、Linux、prometheus监控;并对SQLserver、NoSQL(…...

设置jmeter外观颜色
设置jmeter外观颜色 方法: 步骤一、点击顶部选项 ->外观,这里提供了不同的主题,可选自己喜欢的风格。 步骤二、选择后,弹框提示点击Yes。...

计算机网络 IP 网络层 2 (重置版)
IP的简介: IP 地址是互联网协议地址(Internet Protocol Address)的简称,是分配给连接到互联网的设备的唯一标识符,用于在网络中定位和通信。 IP编制的历史阶段: 1,分类的IP地址: …...

神经网络和深度学习
应用 类型 为什么近几年飞速发展 数据增长,算力增长,算法革新 逻辑回归 向量化 浅层神经网络(Shallow neural network) 单条训练数据前向传播计算表达式 batch训练数据前向传播计算表达式 反向传播计算表达式 参数随机初始化 不能全部设为0 原因是同一…...
MySQL 基础学习(3):排序查询和条件查询
MySQL 查询与条件操作:详解与技巧 在本文中,我们将探讨 MySQL 中的查询操作及其相关功能,包括别名、去重、排序查询和条件查询等,并总结一些最佳实践和注意事项。 一、使用别名(AS) 在查询中,…...

webAPI -DOM 相关知识点总结(非常细)
title: WebAPI语法 date: 2025-01-28 12:00:00 tags:- 前端 categories:- 前端WEB API 了解DOM的结构并掌握其基本的操作,体验 DOM 在开发中的作用 API简介 就是使用js来操作html和浏览器 什么是DOM? 就是一个文档对象模型,是用来呈现预计于任意htm…...

遍历 Map 类型集合的方法汇总
1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...
DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”
目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...
使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度
文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...
Go 语言并发编程基础:无缓冲与有缓冲通道
在上一章节中,我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道,它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好࿰…...

RabbitMQ入门4.1.0版本(基于java、SpringBoot操作)
RabbitMQ 一、RabbitMQ概述 RabbitMQ RabbitMQ最初由LShift和CohesiveFT于2007年开发,后来由Pivotal Software Inc.(现为VMware子公司)接管。RabbitMQ 是一个开源的消息代理和队列服务器,用 Erlang 语言编写。广泛应用于各种分布…...

搭建DNS域名解析服务器(正向解析资源文件)
正向解析资源文件 1)准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2)服务端安装软件:bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...
4. TypeScript 类型推断与类型组合
一、类型推断 (一) 什么是类型推断 TypeScript 的类型推断会根据变量、函数返回值、对象和数组的赋值和使用方式,自动确定它们的类型。 这一特性减少了显式类型注解的需要,在保持类型安全的同时简化了代码。通过分析上下文和初始值,TypeSc…...
苹果AI眼镜:从“工具”到“社交姿态”的范式革命——重新定义AI交互入口的未来机会
在2025年的AI硬件浪潮中,苹果AI眼镜(Apple Glasses)正在引发一场关于“人机交互形态”的深度思考。它并非简单地替代AirPods或Apple Watch,而是开辟了一个全新的、日常可接受的AI入口。其核心价值不在于功能的堆叠,而在于如何通过形态设计打破社交壁垒,成为用户“全天佩戴…...

自然语言处理——文本分类
文本分类 传统机器学习方法文本表示向量空间模型 特征选择文档频率互信息信息增益(IG) 分类器设计贝叶斯理论:线性判别函数 文本分类性能评估P-R曲线ROC曲线 将文本文档或句子分类为预定义的类或类别, 有单标签多类别文本分类和多…...
Python爬虫实战:研究Restkit库相关技术
1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的有价值数据。如何高效地采集这些数据并将其应用于实际业务中,成为了许多企业和开发者关注的焦点。网络爬虫技术作为一种自动化的数据采集工具,可以帮助我们从网页中提取所需的信息。而 RESTful API …...