#线段树,欧拉函数#CF1114F Please, another Queries on Array?
题目
给一个长度为\(n\)的数组\(a\),\(q\)次询问
支持区间乘\(x\)以及求\(\varphi(\prod_{i=l}^ra_i)\)
\(n\leq 4*10^5,q\leq 2*10^5,x\leq 300\)
分析

之前我做过一道这个题目
方法就是建109棵线段树维护每个位置是否能被某个质数整除,以及一个维护区间乘的线段树
然后我把这道题改一改交到本题上结果发现MLE了,我还没发现这两题的区别,对于之前的这道题,还要记录每个位置质数的个数
但是对于这道题,实际上只需要维护一个二进制状态表示质因数分解的情况,然后取出这个二进制状态计算欧拉函数
时间复杂度\(O(qlogn)\)
代码
#include <cstdio>
#include <cctype>
#define rr register
using namespace std;
typedef long long lll; const int N=400011,mod=1000000007; int n,m,a[N],inv[N];
const int prime[62]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293};
inline signed iut(){
rr int ans=0; rr char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans;
}
inline signed ksm(int x,int y){
rr int ans=1;
for (;y;y>>=1,x=1ll*x*x%mod)
if (y&1) ans=1ll*ans*x%mod;
return ans;
}
inline void print(int ans){
if (ans>9) print(ans/10);
putchar(ans%10+48);
}
struct rec{
lll w1,w2;
rec operator *(const rec &t)const{
return (rec){w1*t.w1%mod,w2|t.w2};
}
};
struct segt{
lll lazy[N<<2],Lazy[N<<2]; rec w[N<<2];
inline void build(int k,int l,int r){
lazy[k]=1,Lazy[k]=0;
if (l==r){
w[k].w1=a[l];
for (rr int i=0;i<62;++i)
if (a[l]%prime[i]==0)
w[k].w2|=1ll<<i;
return;
}
rr int mid=(l+r)>>1;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
w[k]=w[k<<1]*w[k<<1|1];
}
inline void spread(int k,int len,int z,lll Z){
lazy[k]=lazy[k]*z%mod,Lazy[k]|=Z;
w[k]=(rec){w[k].w1*ksm(z,len)%mod,w[k].w2|=Z};
}
inline void pushdown(int k,int l,int r,int mid){
if (!Lazy[k]) return;
rr int len1=mid-l+1,len2=r-mid;
spread(k<<1,len1,lazy[k],Lazy[k]);
spread(k<<1|1,len2,lazy[k],Lazy[k]);
lazy[k]=1,Lazy[k]=0;
}
inline rec query(int k,int l,int r,int x,int y){
if (l==x&&r==y) return w[k];
rr int mid=(l+r)>>1; pushdown(k,l,r,mid);
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);
}
inline void update(int k,int l,int r,int x,int y,int z,lll Z){
if (l==x&&r==y){
spread(k,r-l+1,z,Z);
return;
}
rr int mid=(l+r)>>1; pushdown(k,l,r,mid);
if (y<=mid) update(k<<1,l,mid,x,y,z,Z);
else if (x>mid) update(k<<1|1,mid+1,r,x,y,z,Z);
else update(k<<1,l,mid,x,mid,z,Z),update(k<<1|1,mid+1,r,mid+1,y,z,Z);
w[k]=w[k<<1]*w[k<<1|1];
}
}tre;
signed main(){
n=iut(),m=iut();
for (rr int i=0;i<62;++i) inv[i]=1ll*(prime[i]-1)*ksm(prime[i],mod-2)%mod;
for (rr int i=1;i<=n;++i) a[i]=iut();
tre.build(1,1,n);
for (rr char c;m;--m){
c=getchar();
while (c!='T'&&c!='M') c=getchar();
rr int l=iut(),r=iut();
if (c=='T'){
rr rec ANS=tre.query(1,1,n,l,r);
for (rr int i=0;i<62;++i)
if ((ANS.w2>>i)&1){
ANS.w1=1ll*ANS.w1*inv[i]%mod;
}
print(ANS.w1),putchar(10);
}
else{
rr int x=iut(); rr lll T=0;
if (x==1) continue;
for (rr int i=0;i<62;++i)
if (x%prime[i]==0) T|=1ll<<i;
tre.update(1,1,n,l,r,x,T);
}
}
return 0;
}
#线段树,欧拉函数#CF1114F Please, another Queries on Array?的更多相关文章
- 线段树+欧拉函数——cf1114F
调了半天,写线段树老是写炸 /* 两个操作 1.区间乘法 2.区间乘积询问欧拉函数 欧拉函数计算公式 phi(mul(ai))=mul(ai) * (p1-1)/p1 * (p2-1)/p2 * .. ...
- BZOJ 3813--奇数国(线段树&欧拉函数&乘法逆元&状态压缩)
3813: 奇数国 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 755 Solved: 432[Submit][Status][Discuss] ...
- 【bzoj3813】: 奇数国 数论-线段树-欧拉函数
[bzoj3813]: 奇数国 题意:给定一个序列,每个元素可以分解为最小的60个素数的形式.(x=p1^k1*p2^k2*......p60^k60)(p1=2,p2=3,…,p60=281) 支持 ...
- [bzoj3813] 奇数国 [线段树+欧拉函数]
题面 传送门 思路 这题目是真的难读......阅读理解题啊...... 但是理解了以后就发现,题目等价于: 给你一个区间,支持单点修改,以及查询一段区间的乘积的欧拉函数值,这个答案对19961993 ...
- Please, another Queries on Array?(Codeforces Round #538 (Div. 2)F+线段树+欧拉函数+bitset)
题目链接 传送门 题面 思路 设\(x=\prod\limits_{i=l}^{r}a_i\)=\(\prod\limits_{i=1}^{n}p_i^{c_i}\) 由欧拉函数是积性函数得: \[ ...
- Please, another Queries on Array? CodeForces - 1114F (线段树,欧拉函数)
这题刚开始看成求区间$\phi$和了........先说一下区间和的做法吧...... 就是说将题目的操作2改为求$(\sum\limits_{i=l}^{r}\phi(a[i]))\%P$ 首先要知 ...
- BZOJ4869 六省联考2017相逢是问候(线段树+欧拉函数)
由扩展欧拉定理,a^(a^(a^(……^x)))%p中x作为指数的模数应该是φ(φ(φ(φ(……p)))),而p取log次φ就会变为1,也即每个位置一旦被修改一定次数后就会变为定值.线段树维护区间剩余 ...
- 【BZOJ3813】奇数国 线段树+欧拉函数
[BZOJ3813]奇数国 Description 给定一个序列,每次改变一个位置的数,或是询问一段区间的数的乘积的phi值.每个数都可以表示成前60个质数的若干次方的乘积. Sample Input ...
- BZOJ 4026: dC Loves Number Theory 可持久化线段树 + 欧拉函数 + 数学
Code: #include <bits/stdc++.h> #define ll long long #define maxn 50207 #define setIO(s) freope ...
- BZOJ_4026_dC Loves Number Theory _主席树+欧拉函数
BZOJ_4026_dC Loves Number Theory _主席树+欧拉函数 Description dC 在秒了BZOJ 上所有的数论题后,感觉萌萌哒,想出了这么一道水题,来拯救日益枯 竭 ...
随机推荐
- InSAR处理软件——Gamma 安装教程
Gamma是由瑞士 GAMMA Remote Sensing 公司开发SAR数据处理软件,支持SAR数据全流程处理,是最InSAR最常用的软件.下面介绍该软件的安装流程,安装环境为Ubuntu16.0 ...
- Dockerfile和docker-compose详解
Dockerfile镜像制作 docker/podman中, 镜像是容器的基础,每次执行docker run的时候都会指定哪个基本镜像作为容器运行的基础.我们之前的docker的操作都是使用来自doc ...
- 【LeetCode二叉树#07】左叶子节点之和(基于栈的迭代法前中后序遍历复习)
左叶子节点之和 力扣题目链接(opens new window) 计算给定二叉树的所有左叶子之和. 示例: 思路 注意审题,这里是要求 左叶子节点 之和 不是二叉树中的左侧节点之和,因此使用层序遍历是 ...
- 【C++ OOP 03 友元】各种友元例子以及如何类外写成员函数
[友元] 在程序里,有些私有属性 也想让类外特殊的一些函数或者类进行访问,就需要用到友元的技术 友元的目的就是让一个函数或者类 访问另一个类中私有成员 友元的关键字为 friend 友元的三种实现 全 ...
- error LNK2019: unresolved external symbol _CrtDbgReport referenced in function xxxx
现象 在用C++调试dll动态库的时候汇报上述错误,我用VS2015编译的DEBUG版本动态库,实际在VS2019中调试 解决方法 在工程属性中做出如下选择,代码生成->多线程调试DLL ,出现 ...
- 大众点评cat报警源码
类时序 时许说明 判断是否是报警机器. 1分钟启动一个线程根据设置的报警条件,时间段去查询CAT报告数据. 根据返回的报告数据,逐层解析TYPE,NAME,RANGE中的数据是否满足报警条件. 只有全 ...
- 【Azure Function App】Java Function部署到Azure后出现中文显示乱码问题
问题描述 Java Function在Azure上遇见中文显示乱码问题?如何解决呢? 问题解答 中文字符显示为乱码,这个情况就是服务实例上设置的编码格式不是统一的UTF-8所导致的. 在查看Azure ...
- PHP项目&MVC文件安全&上传&包含&下载&删除&读取等
文件安全-文件包含-动态调试-xhcms 1.安装好xhcms,查看index.php文件. 2.存在include关键字,可以存在文件包含漏洞.看上面代码的逻辑,对r的传参添加魔术引号,如果r没有值 ...
- 鸿蒙 Harmony 的跨端技术方案
这两年要说技术上最火的关键字,我想肯定离不开"鸿蒙"两个字. 不管是技术社区还是身边的开发者多多少少都在关注鸿蒙的发展趋势,特别是 HarmonyOS NEXT 版本将进入独立生态 ...
- STM32F103xC,xD,xE引脚定义
STM32F103xC,xD,xE引脚定义 由于在使用STM32系列芯片过程中发现互联网没有整理好的引脚定义,因此自己整理一份,方便以后查阅. GPIOA Pin 重新上电时的功能 默认功能 重映射 ...