给定数列,区间查询和,区间取模,单点修改。
#include<bits/stdc++.h>
using namespace std;
inline int read()
{
int x=0,f=1;char c=getchar();
while(c<'0'||c>'9') {if(c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar();
return x*f;
}
typedef long long ll;
const int maxn=2e5+100;
ll c[maxn<<2],Max[maxn<<2];
int a[maxn],n,m;
void build (int i,int l,int r) {
if (l==r) {
c[i]=Max[i]=a[l];
return;
}
int mid=(l+r)>>1;
build(i<<1,l,mid);
build(i<<1|1,mid+1,r);
c[i]=c[i<<1]+c[i<<1|1];
Max[i]=max(Max[i<<1],Max[i<<1|1]);
}
void up (int i,int l,int r,int p,int v) {
if (l==p&&r==p) {
c[i]=Max[i]=v;
return;
}
int mid=(l+r)>>1;
if (p<=mid) up(i<<1,l,mid,p,v);
if (p>mid) up(i<<1|1,mid+1,r,p,v);
c[i]=c[i<<1]+c[i<<1|1];
Max[i]=max(Max[i<<1],Max[i<<1|1]);
}
void up1 (int i,int l,int r,int L,int R,int v) {
if (Max[i]<v) return;
if (l==r) {
c[i]%=v;
Max[i]%=v;
return;
}
int mid=(l+r)>>1;
if (L<=mid) up1(i<<1,l,mid,L,R,v);
if (R>mid) up1(i<<1|1,mid+1,r,L,R,v);
c[i]=c[i<<1]+c[i<<1|1];
Max[i]=max(Max[i<<1],Max[i<<1|1]);
}
ll query_sum (int i,int l,int r,int L,int R) {
if (l>=L&&r<=R) return c[i];
int mid=(l+r)>>1;
ll ans=0;
if (L<=mid) ans+=query_sum(i<<1,l,mid,L,R);
if (R>mid) ans+=query_sum(i<<1|1,mid+1,r,L,R);
return ans;
}
ll query_max (int i,int l,int r,int L,int R) {
if (l>=L&&r<=R) return Max[i];
int mid=(l+r)>>1;
ll ans=0;
if (L<=mid) ans=max(ans,query_max(i<<1,l,mid,L,R));
if (R>mid) ans=max(ans,query_max(i<<1|1,mid+1,r,l,R));
return ans;
}
int main () {
n=read();
m=read();
for (int i=1;i<=n;i++) a[i]=read();
build(1,1,n);
while (m--) {
int op=read();
if (op==1) {
int l=read();
int r=read();
printf("%lld
",query_sum(1,1,n,l,r));
}
else if (op==2) {
int l=read();
int r=read();
int x=read();
ll y=query_max(1,1,n,l,r);
if (y<x) continue;
else up1(1,1,n,l,r,x);
}
else {
int x=read();
int y=read();
up(1,1,n,x,y);
}
}
}