题意
维护序列:
- 区间求和;
- 单点加;
- 区间开根并下取整。
(n,mleq 10^5),(a_ileq 10^9)。
题解
注意到开根并下取整的操作会很快让 (a_i) 变为 (1)。因此维护区间最大值,对于操作 3,(max a_{[l..r]}=1) 则忽略,否则暴力递归修改。
复杂度 (O(nlog nlog a_i))
#include<cstdio>
#include<iostream>
using namespace std;
const int BUF_LEN=1<<19;
struct FastIO{
char bufi[BUF_LEN+10],*PTi=bufi+BUF_LEN,*PTENDi=bufi+BUF_LEN;
inline char gc(){
(PTi==PTENDi)&&(bufi[fread(bufi,1,BUF_LEN,stdin)]=0,PTi=bufi);
return *(PTi++);
}
char bufo[BUF_LEN+10],*PTo=bufo,*PTENDo=bufo+BUF_LEN;
inline void pc(char c){
(PTo==PTENDo)&&(fwrite(bufo,1,BUF_LEN,stdout),PTo=bufo);
*(PTo++)=c;
}
void flush(){
fwrite(bufo,1,PTo-bufo,stdout);
PTo=bufo;
}
~FastIO(){
flush();
}
template<class T>inline void getint(T &x=0){
char c=gc();
int f=1;x=0;
while(c<'0'||c>'9'){
if(c=='-')f=-1;
c=gc();
}
while(c>='0'&&c<='9'){
x=x*10+c-'0';
c=gc();
}
if(f==-1)x=-x;
}
operator int(){
int v;getint(v);return v;
}
operator long long(){
long long v;getint(v);return v;
}
template<class T>inline void putint(T x=0,char sep=' '){
char tmp[20],len=0;
if(x<0)pc('-'),x=-x;
if(x==0){ pc('0');pc(sep);return; }
while(x)tmp[len++]=x%10,x/=10;
for(int i=len-1;~i;--i)pc(tmp[i]|'0');
pc(sep);
}
}io;
#define ll long long
const int N=1e5+10;
int t[N<<2];
ll tt[N<<2];
void pushup(int x){ t[x]=max(t[x<<1],t[x<<1|1]); tt[x]=tt[x<<1]+tt[x<<1|1]; }
void modify(int l,int r,int k,int x,int nl,int nr){
if(nr<l||nl>r)return;
if(l<=nl&&nr<=r){
if(nl==nr){
t[x]%=k;
tt[x]%=k;
return;
}
int mid=nl+nr>>1;
if(t[x<<1]>=k)modify(l,r,k,x<<1,nl,mid);
if(t[x<<1|1]>=k)modify(l,r,k,x<<1|1,mid+1,nr);
pushup(x);
}else{
int mid=nl+nr>>1;
modify(l,r,k,x<<1,nl,mid);
modify(l,r,k,x<<1|1,mid+1,nr);
pushup(x);
}
}
void modify(int p,int v,int x,int l,int r){
if(l==r){t[x]=tt[x]=v;return;}
int mid=l+r>>1;
if(p<=mid)modify(p,v,x<<1,l,mid);
else modify(p,v,x<<1|1,mid+1,r);
pushup(x);
}
ll query(int l,int r,int x,int nl,int nr){
if(nr<l||nl>r)return 0;
if(l<=nl&&nr<=r)return tt[x];
int mid=nl+nr>>1;
return query(l,r,x<<1,nl,mid)+query(l,r,x<<1|1,mid+1,nr);
}
int a[N];
void build(int x,int l,int r){
if(l==r){
t[x]=tt[x]=a[l];
return;
}
int mid=l+r>>1;
build(x<<1,l,mid);
build(x<<1|1,mid+1,r);
pushup(x);
}
int main(){
int n=io,m=io;
for(int i=1;i<=n;i++)a[i]=io;
build(1,1,n);
while(m--){
int op=io;
if(op==1){
int l=io,r=io;
io.putint(query(l,r,1,1,n),'
');
}
if(op==2){
int l=io,r=io,k=io;
modify(l,r,k,1,1,n);
}
if(op==3){
int p=io,v=io;
modify(p,v,1,1,n);
}
}
}