rt,就是使用线段树维护区间和和区间乘积最小,但是tle on #20
https://www.luogu.com.cn/record/169517448
#include<bits/stdc++.h>
typedef long ll;
using namespace std;
inline ll read(){ll x=0,f=1;char c=getchar();while(c<48||c>57){if(c==45)f=0;c=getchar();}while(c>47&&c<58)x=(x<<3)+(x<<1)+(c^48),c=getchar();return f?x:-x;}
inline void write(ll x){if(!x){putchar(48);putchar('\n');return;}ll top=0,s[40];if(x<0)x=-x,putchar(45);while(x)s[top++]=x%10^48,x/=10;while(top--)putchar(s[top]);putchar('\n');}
const ll mod=1e9+7,maxn=1e5+5,maxt=505;
ll n,m,a[maxn],b[maxn];
struct node{
int l,r;
ll mn,sum;
}t[maxn<<2];
inline void pushup(int x){
t[x].sum=t[x<<1].sum+t[x<<1|1].sum;
t[x].mn=min(t[x<<1].mn,t[x<<1|1].mn);
}
inline void build(int x,int l,int r){
t[x].l=l,t[x].r=r;
if(l==r){
t[x].mn=a[l]*b[l];
t[x].sum=a[l]+b[l];
return;
}int mid=(t[x].l+t[x].r)>>1;
build(x<<1,l,mid);
build(x<<1|1,mid+1,r);
pushup(x);
}
inline void update(int x,int pos,ll k1,ll k2){
if(t[x].l==t[x].r){
t[x].sum=k1+k2;
t[x].mn=k1*k2;
a[pos]=k1,b[pos]=k2;
return;
}int mid=(t[x].l+t[x].r)>>1;
if(pos<=mid)update(x<<1,pos,k1,k2);
else update(x<<1|1,pos,k1,k2);
pushup(x);
}
inline void add(int x,int l,int r,ll lim,ll k){
if(t[x].mn>lim)return;
if(t[x].l==t[x].r){
a[t[x].l]+=k,b[t[x].l]+=k;
t[x].mn=a[t[x].l]*b[t[x].l],t[x].sum+=k*2;
return;
}int mid=(t[x].l+t[x].r)>>1;
if(l<=mid)add(x<<1,l,r,lim,k);
if(r>mid)add(x<<1|1,l,r,lim,k);
pushup(x);
}
inline ll query(int x,int l,int r){
if(l<=t[x].l&&t[x].r<=r)return t[x].sum;
ll ans=0;int mid=(t[x].l+t[x].r)>>1;
if(l<=mid)ans+=query(x<<1,l,r);
if(r>mid)ans+=query(x<<1|1,l,r);
return ans;
}
signed main(){
n=read(),m=read();
for(ll i=1;i<=n;++i)a[i]=read();
for(ll i=1;i<=n;++i)b[i]=read();
build(1,1,n);
while(m--){
int op=read();
if(op==1){
int l=read(),r=read(),lim=read(),k=read();
if(!lim)continue;
add(1,l,r,lim,k);
}
else if(op==2){
int pos=read(),k1=read(),k2=read();
update(1,pos,k1,k2);
}
else{
int l=read(),r=read();
write(query(1,l,r));
}
}
return 0;
}