code:
#include "bits/stdc++.h"
using namespace std;
#define Long long long int
const Long Mod=1000000007;
struct SegmentTree{
int Left,Right;
Long Sum,Squ;
}Tree[1440000];
Long InPut[1440000];
int N,M;
inline Long Read(void){
Long X=0,Y=1;char C=getchar();
while(C<'0'||C>'9'){if(C=='-'){Y=-1;}C=getchar();}
while('0'<=C&&C<='9'){X=X*10+(C-'0');C=getchar();}
return (X*Y);
}
inline int LeftSon(int i){return i<<1;}
inline int RightSon(int i){return i<<1|1;}
inline void Build(int i,int Left,int Right){
Tree[i].Left=Left;
Tree[i].Right=Right;
if(Left==Right){
Tree[i].Squ=(InPut[Left]*InPut[Left])%Mod;
Tree[i].Sum=InPut[Left]%Mod;
return;
}
int Mid=(Left+Right)>>1;
int L=LeftSon(i),R=RightSon(i);
Build(L,Left,Mid),Build(R,Mid+1,Right);
Tree[i].Sum=(Tree[L].Sum+Tree[R].Sum)%Mod;
Tree[i].Squ=(Tree[L].Squ+Tree[R].Squ)%Mod;
return;
}
inline void Change(int i,int W,Long C){
if(Tree[i].Right<W||Tree[i].Left>W)
return;
if(Tree[i].Left==Tree[i].Right){
Tree[i].Squ=C*C%Mod;
Tree[i].Sum=C%Mod;
return;
}
int L=LeftSon(i),R=RightSon(i);
if(Tree[L].Right>=W)Change(L,W,C);
if(Tree[R].Left<=W)Change(R,W,C);
Tree[i].Squ=(Tree[L].Squ+Tree[R].Squ)%Mod;
Tree[i].Sum=(Tree[L].Sum+Tree[R].Sum)%Mod;
return;
}
inline Long SearchSqu(int Left,int Right,int i){
if(Left>Tree[i].Right||Tree[i].Left>Right)
return 0;
if(Left<=Tree[i].Left&&Tree[i].Right<=Right)
return Tree[i].Squ%Mod;
Long S=0;
int L=LeftSon(i),R=RightSon(i);
if(Tree[L].Right>=Left)
S=(S+SearchSqu(Left,Right,L))%Mod;
if(Tree[R].Left<=Right)
S=(S+SearchSqu(Left,Right,R))%Mod;
return S;
}
inline Long SearchSum(int Left,int Right,int i){
if(Left>Tree[i].Right||Tree[i].Left>Right)
return 0;
if(Left<=Tree[i].Left&&Tree[i].Right<=Right)
return Tree[i].Sum%Mod;
Long S=0;
int L=LeftSon(i),R=RightSon(i);
if(Tree[L].Right>=Left)
S=(S+SearchSum(Left,Right,L))%Mod;
if(Tree[R].Left<=Right)
S=(S+SearchSum(Left,Right,R))%Mod;
return S;
}
Long qpow(Long x){
Long res=1;
for(int y=Mod-2;y;y>>=1,x=(x*x)%Mod)
if(y&1)
(res*=x)%=Mod;
return res;
}
int Do,Len;
Long X,Y,Square,SumB,A;
int main(void){
N=Read(),M=Read();
for(register int i=1;i<=N;i++)
InPut[i]=Read();
Build(1,1,N);
for(register int i=1;i<=M;i++){
Do=Read();
X=Read(),Y=Read();
if(Do==1){
Change(1,X,Y%Mod);
}else if(Do==2){
Len=(Y-X+1);
Square=SearchSqu(X,Y,1)%Mod;
SumB=SearchSum(X,Y,1)%Mod;
SumB=(SumB*SumB)%Mod;
A=(Mod+Mod+Mod+(Square*Len)%Mod-SumB)%Mod;
Len=qpow(Len*Len)%Mod;
A=(A*Len)%Mod;
cout<<A<<endl;
}
}
return 0;
}