代码如下:
#include<bits/stdc++.h>
#define int long long
const int N=100005;
const int mod=1e9+7;
using namespace std;
int n,m,b[N],sqsum[N<<2],sum[N<<2];
int qpow(int a,int b){
int s=1;
while(b){
if(b&1LL) s=s*a%mod;
a=a*a%mod;
b>>=1LL;
}
return s;
}
void push_up(int rt){
sqsum[rt]=(sqsum[rt<<1]+sqsum[rt<<1|1])%mod;
sum[rt]=(sum[rt<<1]+sum[rt<<1|1])%mod;
}
void build(int l,int r,int rt){
if(l==r){
sqsum[rt]=b[l]*b[l]%mod;sum[rt]=b[l];
return;
}
int mid=l+r>>1;
build(l,mid,rt<<1);
build(mid+1,r,rt<<1|1);
push_up(rt);
}
void update(int l,int r,int rt,int a,int b){
if(l==r){
sqsum[rt]=b*b%mod;sum[rt]=b;
return;
}
int mid=l+r>>1;
if(a<=mid) update(l,mid,rt<<1,a,b);
else update(mid+1,r,rt<<1|1,a,b);
push_up(rt);
}
int query_sqsum(int l,int r,int rt,int a,int b){
if(a<=l&&b>=r) return sqsum[rt];
int mid=l+r>>1,ans=0;
if(a<=mid) ans=(ans+query_sqsum(l,mid,rt<<1,a,b))%mod;
if(b>mid) ans=(ans+query_sqsum(mid+1,r,rt<<1|1,a,b))%mod;
return ans;
}
int query_sum(int l,int r,int rt,int a,int b){
if(a<=l&&b>=r) return sum[rt];
int mid=l+r>>1,ans=0;
if(a<=mid) ans=(ans+query_sum(l,mid,rt<<1,a,b))%mod;
if(b>mid) ans=(ans+query_sum(mid+1,r,rt<<1|1,a,b))%mod;
return ans;
}
int query(int l,int r){
int s1=query_sqsum(1,n,1,l,r),s2=query_sum(1,n,1,l,r);
return (((r-l+1)*s1%mod-s2*s2%mod)%mod*qpow((r-l+1)*(r-l+1),mod-2)%mod+mod)%mod;
}
signed main(){
scanf("%lld%lld",&n,&m);
for(int i=1;i<=n;i++) scanf("%lld",&b[i]);
build(1,n,1);
while(m--){
int c,x,y;scanf("%lld%lld%lld",&c,&x,&y);
if(c==1) update(1,n,1,x,y);
else printf("%lld\n",query(x,y));
}
return 0;
}