Subtask #1、#4 WA 了,求调。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
using std::cin;using std::cout;
constexpr int N=200005,mod=1e9+7;
int n,m,c[N],opt,l,r,x;
std::vector<std::pair<int,int> >d[N];
struct SegmentTree{
#define ls (p<<1)
#define rs (p<<1|1)
#define mid ((l+r)>>1)
int a[N<<2],b[N<<2],add[N<<2],mul[N<<2],blocks[N<<2],len[N<<2];
inline void pushup(int p){
a[p]=(a[ls]+a[rs])%mod;
b[p]=(b[ls]+b[rs])%mod;
len[p]=len[ls]+len[rs];
}
inline void pushdown(int p){
if(!blocks[ls]){
a[ls]=(1ll*a[ls]*mul[p]%mod+1ll*add[p]*len[ls]%mod)%mod;
add[ls]=(1ll*add[ls]*mul[p]%mod+add[p])%mod;
mul[ls]=1ll*mul[ls]*mul[p]%mod;
}
if(!blocks[rs]){
a[rs]=(1ll*a[rs]*mul[p]%mod+1ll*add[p]*len[rs]%mod)%mod;
add[rs]=(1ll*add[rs]*mul[p]%mod+add[p])%mod;
mul[rs]=1ll*mul[rs]*mul[p]%mod;
}
add[p]=0;mul[p]=1;
}
inline void build(int l,int r,int p){
mul[p]=1;
if(l==r){a[p]=c[l];len[p]=1;return ;}
build(l,mid,ls);build(mid+1,r,rs);
pushup(p);
}
inline void updateadd(int l,int r,int x,int y,int p,int k){
if(blocks[p]) return ;
if(x<=l&&r<=y){
a[p]=(a[p]+1ll*len[p]*k%mod)%mod;
add[p]=(add[p]+k)%mod;
return ;
}
pushdown(p);
if(x<=mid) updateadd(l,mid,x,y,ls,k);
if(mid<y) updateadd(mid+1,r,x,y,rs,k);
pushup(p);
}
inline void updatemul(int l,int r,int x,int y,int p,int k){
if(blocks[p]) return ;
if(x<=l&&r<=y){
a[p]=1ll*a[p]*k%mod;
add[p]=1ll*add[p]*k%mod;
mul[p]=1ll*mul[p]*k%mod;
return ;
}
pushdown(p);
if(x<=mid) updatemul(l,mid,x,y,ls,k);
if(mid<y) updatemul(mid+1,r,x,y,rs,k);
pushup(p);
}
inline void lock(int l,int r,int x,int y,int p){
if(x<=l&&r<=y){
if(l!=r) pushdown(p);
if(!blocks[p]){b[p]=(b[p]+a[p])%mod;a[p]=len[p]=0;}
++blocks[p];
return ;
}
pushdown(p);
if(x<=mid) lock(l,mid,x,y,ls);
if(mid<y) lock(mid+1,r,x,y,rs);
pushup(p);
}
inline void unlock(int l,int r,int x,int y,int p){
if(x<=l&&r<=y){
--blocks[p];
if(!blocks[p]){
if(l==r){std::swap(a[p],b[p]);len[p]=1;}
else pushup(p);
}
return ;
}
pushdown(p);
if(x<=mid) unlock(l,mid,x,y,ls);
if(mid<y) unlock(mid+1,r,x,y,rs);
pushup(p);
}
inline int query(int l,int r,int x,int y,int p){
if(x<=l&&r<=y) return (a[p]+b[p])%mod;
pushdown(p);
int sum=0;
if(x<=mid) sum=(sum+query(l,mid,x,y,ls))%mod;
if(mid<y) sum=(sum+query(mid+1,r,x,y,rs))%mod;
return sum;
}
}tree;
signed main(){
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
std::ios::sync_with_stdio(false);
cin.tie(nullptr);cout.tie(nullptr);
cin>>n>>m;
for(int i=1;i<=n;++i) cin>>c[i];
tree.build(1,n,1);
for(int i=1;i<=m;++i){
cin>>opt>>l>>r;
if(opt==1){cin>>x;tree.updateadd(1,n,l,r,1,x);}
if(opt==2){cin>>x;tree.updatemul(1,n,l,r,1,x);}
if(opt==3){cin>>x;tree.lock(1,n,l,r,1);d[i+x].emplace_back(l,r);}
if(opt==4) cout<<tree.query(1,n,l,r,1)<<'\n';
for(auto j:d[i]) tree.unlock(1,n,j.first,j.second,1);
// for(int j=1;j<=n;++j) cout<<tree.query(1,n,j,j,1)<<(j==n?'\n':' ');
}
return 0;
}