CF1114F Please, another Queries on Array?
一道很好的线段树+求欧拉函数题!!!
先简单理解一下题意:给你一段长度为n的区间,q次操作,输入为1时将l~r区间每个数乘上x,输入为2时求解
赛时心历经过:
第一眼感觉是个线段树板子题,赛时也是这么想的,打到一半发现不对劲,首先这个乘积就没法维护,随便乘两下就炸了,再其次这么大的数我也不会求
赛后去查了一下怎么能利用
其中
这样搞的话就可以边
用线段树维护两个东西一个是
把
问题迎刃而解!!!
最后附上代码::
#include<bits/stdc++.h>
#define int long long
#define ls rt<<1
#define rs rt<<1|1
using namespace std;
const int N=4e5+5,p=1e9+7;
int n,m,t;
int z,x,y,tot,a[N];
int phi[N],prime[N];
string op;
struct sb{
int l,r,x,lazy1,lazy2=1,size,phi;
}tr[N<<2];
int qp(int a,int n){
int ans=1;
while(n){
if(n&1)ans=ans*a%p;
a=a*a%p;
n>>=1;
}
return ans;
}
int ny(int x){
return qp(x,p-2);
}
void iint(){
for(int i=2;i<=300;i++){
bool vis=0;
for(int j=2;j<=sqrt(i);j++){
if(i%j==0)vis=1;
}if(vis==0)prime[++tot]=i,phi[tot]=(i-1)*ny(i)%p;
}
}
void pushup(int rt){
tr[rt].x=tr[ls].x*tr[rs].x%p;
tr[rt].size=tr[ls].size+tr[rs].size;
tr[rt].phi=(tr[ls].phi|tr[rs].phi);
}
void pushdown(int rt){
int l1=tr[rt].lazy1;
if(l1){
tr[ls].phi=(tr[ls].phi|l1);
tr[rs].phi=(tr[rs].phi|l1);
tr[ls].lazy1|=l1;
tr[rs].lazy1|=l1;
tr[rt].lazy1=0;
}
int l2=tr[rt].lazy2;
if(l2!=1){
tr[ls].x=tr[ls].x*qp(l2,tr[ls].size)%p;
tr[rs].x=tr[rs].x*qp(l2,tr[rs].size)%p;
tr[ls].lazy2=tr[ls].lazy2*l2%p;
tr[rs].lazy2=tr[rs].lazy2*l2%p;
tr[rt].lazy2=1;
}
}
void build(int rt,int l,int r){
tr[rt].l=l;
tr[rt].r=r;
if(l==r){
tr[rt].x=a[l];
tr[rt].size=1;
for(int i=1;i<=tot;i++){
if(a[l]%prime[i]==0){
tr[rt].phi=(tr[rt].phi|(1ll<<i));
}
}
return;
}
int mid=(l+r)>>1;
build(ls,l,mid);
build(rs,mid+1,r);
pushup(rt);
}
void change(int rt,int l,int r,int x){
if(tr[rt].l>=l&&tr[rt].r<=r){
int sum=0;
for(int i=1;i<=tot;i++){
if(x%prime[i]==0){
sum=(sum|(1ll<<i));
}
}
tr[rt].x=tr[rt].x*qp(x,tr[rt].size)%p;
tr[rt].phi|=sum;
tr[rt].lazy1|=sum;
tr[rt].lazy2=tr[rt].lazy2*x%p;
return;
}
pushdown(rt);
int mid=(tr[rt].l+tr[rt].r)>>1;
if(l<=mid)change(ls,l,r,x);
if(r>mid)change(rs,l,r,x);
pushup(rt);
}
int query(int rt,int l,int r){
pushdown(rt);
if(tr[rt].l>=l&&tr[rt].r<=r)return tr[rt].x;
int mid=(tr[rt].l+tr[rt].r)>>1;
int ans=1;
if(l<=mid)ans=ans*query(ls,l,r)%p;
if(r>mid)ans=ans*query(rs,l,r)%p;
return ans%p;
}
int Query(int rt,int l,int r){
pushdown(rt);
if(tr[rt].l>=l&&tr[rt].r<=r){
return tr[rt].phi;
}
int mid=(tr[rt].l+tr[rt].r)>>1;
int ans=0;
if(l<=mid)ans=(ans|Query(ls,l,r));
if(r>mid)ans=(ans|Query(rs,l,r));
return ans;
}
signed main(){
// freopen("array.in","r",stdin);
// freopen("array.out","w",stdout);
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
iint();
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
}
build(1,1,n);
while(m--){
cin>>op>>x>>y;
if(op[0]=='1'){
cin>>z;
change(1,x,y,z);
}
else{
int k=Query(1,x,y);
int sum=1;
for(int i=1;i<=62;i++){
if((k>>i)&1)sum=sum*phi[i]%p;
}
int aaa=query(1,x,y);
cout<<aaa*sum%p<<endl;
}
}
return 0;
}
完结撒花!!!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具