#线段树#洛谷 4681 [THUSC2015]平方运算
题目
给定一个数列 \(a\),维护以下两种操作
- 区间取平方 \(a[i]=a[i]^2\bmod p\)
- 区间和(不取模)
\(p\) 为给定的小于 \(10^4\) 的数,\(n\leq 10^5\)
分析
由于这个模数比较小,不妨猜想它最终会以某种形式结束。
但是不是结束在一个数,可能最后进入一个循环节。
所以在线段树上维护这个区间的循环节循环到第几个位置。
可以发现循环节大小最多为 \(60\),那么时间复杂度为 \(O(60n\log{n})\)
代码
#include <cstdio>
#include <cctype>
#include <algorithm>
#include <queue>
using namespace std;
const int N=100011; bool loop[N<<2],cir[N]; int lcm[71][71]; queue<int>q;
int w[N<<2][71],len[N<<2],nxt[N],a[N],pos[N<<2],n,m,mod,lazy[N<<2],deg[N];
int iut(){
int ans=0; char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=ans*10+c-48,c=getchar();
return ans;
}
void print(int ans){
if (ans>9) print(ans/10);
putchar(ans%10+48);
}
void Get(int k,int x){
loop[k]=cir[x],w[k][pos[k]=0]=x,len[k]=1;
if (loop[k]){
for (int y=nxt[x];y!=x;y=nxt[y])
w[k][len[k]++]=y;
}
}
void pup(int k){
loop[k]=loop[k<<1]&loop[k<<1|1],pos[k]=0;
len[k]=lcm[len[k<<1]][len[k<<1|1]];
int t0=pos[k<<1],t1=pos[k<<1|1];
for (int i=0;i<len[k];++i){
w[k][i]=w[k<<1][t0++]+w[k<<1|1][t1++];
if (t0==len[k<<1]) t0=0;
if (t1==len[k<<1|1]) t1=0;
}
}
void ptag(int k,int z){
lazy[k]=(lazy[k]+z)%len[k],pos[k]=(pos[k]+z)%len[k];
}
void build(int k,int l,int r){
if (l==r){
Get(k,a[l]);
return;
}
int mid=(l+r)>>1;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
pup(k);
}
void update(int k,int l,int r,int x,int y){
if (x<=l&&r<=y&&loop[k]) {ptag(k,1); return;}
if (l==r) {a[l]=nxt[a[l]],Get(k,a[l]); return;}
int mid=(l+r)>>1;
if (lazy[k]){
ptag(k<<1,lazy[k]);
ptag(k<<1|1,lazy[k]);
lazy[k]=0;
}
if (x<=mid) update(k<<1,l,mid,x,y);
if (y>mid) update(k<<1|1,mid+1,r,x,y);
pup(k);
}
int query(int k,int l,int r,int x,int y){
if (l==x&&r==y) return w[k][pos[k]];
int mid=(l+r)>>1;
if (lazy[k]){
ptag(k<<1,lazy[k]);
ptag(k<<1|1,lazy[k]);
lazy[k]=0;
}
if (y<=mid) return query(k<<1,l,mid,x,y);
else if (x>mid) return query(k<<1|1,mid+1,r,x,y);
else return query(k<<1,l,mid,x,mid)+query(k<<1|1,mid+1,r,mid+1,y);
}
int main(){
n=iut(),m=iut(),mod=iut();
for (int i=1;i<71;++i)
for (int j=1;j<71;++j)
lcm[i][j]=i*j/__gcd(i,j);
for (int i=0;i<mod;++i) ++deg[nxt[i]=i*i%mod],cir[i]=1;
for (int i=0;i<mod;++i) if (!deg[i]) q.push(i);
while (!q.empty()){
int x=q.front(); q.pop(),cir[x]=0;
if (!(--deg[nxt[x]])) q.push(nxt[x]);
}
for (int i=1;i<=n;++i) a[i]=iut();
build(1,1,n);
for (int i=1;i<=m;++i){
int opt=iut(),l=iut(),r=iut();
if (opt==1) print(query(1,1,n,l,r)),putchar(10);
else update(1,1,n,l,r);
}
return 0;
}
#线段树#洛谷 4681 [THUSC2015]平方运算的更多相关文章
- 线段树 洛谷P3932 浮游大陆的68号岛
P3932 浮游大陆的68号岛 题目描述 妖精仓库里生活着黄金妖精们,她们过着快乐,却随时准备着迎接死亡的生活. 换用更高尚的说法,是随时准备着为这个无药可救的世界献身. 然而孩子们的生活却总是无忧无 ...
- [线段树]洛谷P5278 算术天才⑨与等差数列
题目描述 算术天才⑨非常喜欢和等差数列玩耍. 有一天,他给了你一个长度为n的序列,其中第i个数为a[i]. 他想考考你,每次他会给出询问l,r,k,问区间[l,r]内的数从小到大排序后能否形成公差为k ...
- 区间连续长度的线段树——洛谷P2894 [USACO08FEB]酒店Hotel
https://www.luogu.org/problem/P2894 #include<cstdio> #include<iostream> using namespace ...
- BZOJ4105 THUSC2015平方运算(线段树)
注意到模数被给出且非常小,做法肯定要依赖于一些与此相关的性质.找题解打表可以发现循环节长度的lcm不超过60. 考虑怎么用线段树维护循环.对线段树上每个点维护这段区间的循环节.在循环中的位置,如果未进 ...
- poj 2777 Count Color(线段树、状态压缩、位运算)
Count Color Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 38921 Accepted: 11696 Des ...
- AC日记——校门外的树 洛谷 P1047
题目描述 某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米.我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置:数轴上的每个整数点,即0,1,2,……,L,都种 ...
- 带修主席树 洛谷2617 支持单点更新以及区间kth大查询
题目链接:https://www.luogu.com.cn/problem/P2617 参考博客:https://blog.csdn.net/dreaming__ldx/article/details ...
- 洛谷——P1226 取余运算||快速幂
P1226 取余运算||快速幂 题目描述 输入b,p,k的值,求b^p mod k的值.其中b,p,k*k为长整型数. 输入输出格式 输入格式: 三个整数b,p,k. 输出格式: 输出“b^p mod ...
- 洛谷 P1226 取余运算||快速幂
P1226 取余运算||快速幂 题目描述 输入b,p,k的值,求b^p mod k的值.其中b,p,k*k为长整型数. 输入输出格式 输入格式: 三个整数b,p,k. 输出格式: 输出“b^p mod ...
- 洛谷 - P1582 - 倒水 - 位运算
https://www.luogu.org/problemnew/show/P1582 要求用最少的瓶子,那肯定不能有两个一样的瓶子,否则合并更优. 枚举其二进制位,每次加上lowbit,将最后一个1 ...
随机推荐
- RK3568开发笔记(三):RK3568虚拟机基础环境搭建之更新源、安装网络工具、串口调试、网络连接、文件传输、安装vscode和samba共享服务
前言 开始搭建RK3568的基础虚拟机,具备基本的通用功能,主要包含了串口工具minicom,远程登陆ssh,远程传输filezilla,代码编辑工具vscode. 虚拟机 文档对对虚拟机 ...
- 记录问题:goland无法识别sdk的问题
goland版本:2020 go版本:1.20.3最新版 在goland中配置GOROOT时找不到sdk 解决版本: > cd /usr/local/go # 我本地go的安装目录 > c ...
- 对find命令结果进行操作
# find匹配到一些文件后,可能希望对其进行一些操作,这时就可以使用-exec选项,exec选项后面跟着所要执行的命令,然后是一对{},一个空格和一个\,最后是一个分号; find . -type ...
- 【LeetCode剑指offer#04】包含min函数的栈、栈的压入、弹出序列(辅助栈的应用)
包含min函数的栈 https://leetcode.cn/problems/bao-han-minhan-shu-de-zhan-lcof/ 定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元 ...
- Spring Cloud Zuul 获取当前请求的路由信息和路由后端的服务节点信息
基本思路 参考spring-cloud-zuul-ratelimit开源项目,在过滤器中根据当前的请求路径,判断当前的路由信息,当取得路由信息后,可以对服务的调用次数做统计等操作. 具体实现 创建一个 ...
- 【Azure 存储服务】Azure Blob上传大文件(600MB)出现内存溢出情况(Java SDK)
问题描述 Java 云端开发,调用 blob 上传会产生内存溢出,Java上调用的方式如下: InputStream inputStream = new BufferedInputStream(new ...
- 答应我,在vue中不要滥用watch好吗?
前言 上周五晚上8点,开开心心的等着产品验收完毕后就可以顺利上线.结果产品突然找到我说要加需求,并且维护这一块业务的同事已经下班走了,所以只有我来做.虽然内心一万头草泥马在狂奔,但是嘴里还是一口答应没 ...
- 【Filament】材质系统
1 前言 本文主要介绍 Filament 的材质系统,官方介绍详见 → Filament Materials Guide.材质系统中会涉及到一些空间和变换的知识点,可以参考:[Unity3D]空间 ...
- Java 常用类 JDK 8 之前日期和时间的API测试
1 package com.bytezero.stringclass; 2 3 import org.junit.Test; 4 5 import java.util.Date; 6 7 8 /** ...
- CPN Tools 系统建模分析工具(持续更新)
一直想把之前看有关CPN的文献资料做一个综合性的整理,所以最近花了些时间,把乌克兰敖德萨国家电信科学院交通运输部学院的讲义做一个翻译.本课程的翻译不具授权(如有侵权请及时联系,做删除处理) 本课程的标 ...