操作1.单点修改
操作2.计算d
d的式子一定要化简到底,而且分母越小越好,不然很难处理,因此不要通分或者分子上去分母
所以我们知道要维护平方和以及和
逆元板子
ll qmi(ll a,ll b){
ll res=1;
a%=mod;
while(b){
if(b&1ll){
res=res*a%mod;
}
a=a*a%mod;
b>>=1ll;
}
return res;
}
ll inv(ll x){return qmi(x,mod-2)%mod;}
// Problem: P5142 区间方差
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P5142
// Memory Limit: 125 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include<iostream>
using namespace std;
typedef long long ll;
const int N=1e5+9;
const ll mod=1e9+7;
ll a[N];
struct node{
ll val,pfval;
}seg[N<<2];
ll work(ll x){
x+=mod;
x%=mod;
return x;
}
ll tl(ll x){return x<<1;}
ll tr(ll x){return x<<1|1;}
ll qmi(ll a,ll b){
ll res=1;
a%=mod;
while(b){
if(b&1ll){
res=res*a%mod;
}
a=a*a%mod;
b>>=1ll;
}
return res;
}
ll inv(ll x){return qmi(x,mod-2)%mod;}
void pushup(int id){
seg[id].val=(seg[tl(id)].val+seg[tr(id)].val)%mod;
seg[id].pfval=(seg[tl(id)].pfval+seg[tr(id)].pfval)%mod;
}
void build(int id,int l,int r){
if(l==r){
seg[id].val=a[l]%mod;
seg[id].pfval=a[l]*a[l]%mod;
return;
}
int mid=(l+r)>>1;
build(tl(id),l,mid);
build(tr(id),mid+1,r);
pushup(id);
}
void update(int id,int l,int r,int pos,ll v){
if(l==r){
seg[id].val=v%mod;
seg[id].pfval=v*v%mod;
return;
}
int mid=(l+r)>>1;
if(mid>=pos){
update(tl(id),l,mid,pos,v);
}else{
update(tr(id),mid+1,r,pos,v);
}
pushup(id);
}
bool inrange(int L,int R,int l,int r){return L>=l && R<=r;}
bool outofrange(int L,int R,int l,int r){return L>r || l>R;}
ll query1(int id,int L,int R,int l,int r){
if(inrange(L,R,l,r)){
return seg[id].val%mod;
}else if(!outofrange(L,R,l,r)){
int mid=(L+R)>>1;
return (query1(tl(id),L,mid,l,r)+query1(tr(id),mid+1,R,l,r))%mod;
}else{
return 0;
}
}
ll query2(int id,int L,int R,int l,int r){
if(inrange(L,R,l,r)){
return seg[id].pfval%mod;
}else if(!outofrange(L,R,l,r)){
int mid=(L+R)>>1;
return (query2(tl(id),L,mid,l,r)+query2(tr(id),mid+1,R,l,r))%mod;
}else{
return 0;
}
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
a[i]%=mod;
}
build(1,1,n);
for(int i=1;i<=m;i++){
int op,x,y;
cin>>op>>x>>y;
if(op==1){
y%=mod;
update(1,1,n,x,y);
}else{
ll len=y-x+1;
ll a=query2(1,1,n,x,y);
a=work(a);
a*=inv(len);
a=work(a);
len*=len;
len=work(len);
ll b=query1(1,1,n,x,y);
b*=b;
b=work(b);
b*=inv(len);
b=work(b);
ll ans=a-b;
ans=work(ans);
cout<<ans<<'\n';
}
}
return 0;
}