题意:
长度为n的序列,初始每个元素为1,q次操作
操作有两种:
1.给定区间,将这个区间中的每个数乘上一个x,2<=x<=10
2.查询区间中pos(x)的最值,其中pos(x)的定义如下:
其实pos(x)就是x质因子分解之后每个质因子幂次中的最大值
数据范围:n<=1e5
解法:
观察到x只有10,10以内的质数只有2、3、5、7
开4棵线段树维护每个位置上质因子的幂次即可,需要区间加法
查询的时候要用区间最值
code:
#include<bits/stdc++.h>
using namespace std;
const int maxm=1e5+5;
int n,m;
struct Node{
int a[maxm<<2];
int laz[maxm<<2];
void pushup(int node){
a[node]=max(a[node*2],a[node*2+1]);
}
void pushdown(int node){
if(laz[node]){
int lz=laz[node];
laz[node*2]+=lz;
laz[node*2+1]+=lz;
a[node*2]+=lz;
a[node*2+1]+=lz;
laz[node]=0;
}
}
void build(int l,int r,int node){
a[node]=0;
laz[node]=0;
if(l==r)return;
int mid=(l+r)/2;
build(l,mid,node*2);
build(mid+1,r,node*2+1);
}
void update(int st,int ed,int val,int l,int r,int node){
if(st<=l&&ed>=r){
a[node]+=val;
laz[node]+=val;
return ;
}
pushdown(node);
int mid=(l+r)/2;
if(st<=mid){
update(st,ed,val,l,mid,node*2);
}
if(ed>=mid+1){
update(st,ed,val,mid+1,r,node*2+1);
}
pushup(node);
}
int ask(int st,int ed,int l,int r,int node){
if(st<=l&&ed>=r){
return a[node];
}
pushdown(node);
int mid=(l+r)/2;
int ans=0;
if(st<=mid){
ans=max(ans,ask(st,ed,l,mid,node*2));
}
if(ed>=mid+1){
ans=max(ans,ask(st,ed,mid+1,r,node*2+1));
}
pushup(node);
return ans;
}
}t[4];
void check(int st,int ed,int num,int x){
int cnt=0;
while(num&&num%x==0){
num/=x;
cnt++;
}
if(cnt){
if(x==2){
t[0].update(st,ed,cnt,1,n,1);
}else if(x==3){
t[1].update(st,ed,cnt,1,n,1);
}else if(x==5){
t[2].update(st,ed,cnt,1,n,1);
}else if(x==7){
t[3].update(st,ed,cnt,1,n,1);
}
}
}
signed main(){
scanf("%d%d",&n,&m);
for(int i=0;i<4;i++){
t[i].build(1,n,1);
}
char s[15];
while(m--){
scanf("%s",s);
if(s[1]=='U'){//mul
int l,r,x;
scanf("%d%d%d",&l,&r,&x);
check(l,r,x,2);
check(l,r,x,3);
check(l,r,x,5);
check(l,r,x,7);
}else{//max
int l,r;
scanf("%d%d",&l,&r);
int ans=0;
for(int i=0;i<4;i++){//取所有树中的最大值
ans=max(ans,t[i].ask(l,r,1,n,1));
}
printf("ANSWER %d\n",ans);
}
}
return 0;
}