具体思路是用 lrm 维护每个点上的值是由左(0)、右(1)、整个(2)传上来的
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int MAXN=200005,MAXFLOW=1ll<<30;
int n,q,a[MAXN];
struct Tree{
int l,r,v,lrm;// l为取左区间,r为取右区间,m为左右相乘
}t[MAXN<<2|1];
inline int getmax(int xx,int yy,int &lrm){
int x=t[xx].v,y=t[yy].v;
if(t[xx].lrm==2||t[yy].lrm==2||(t[xx].lrm==1&&t[yy].lrm==0)){
if((!~x)&&(!~y)){
lrm=2;
return -1;
}else if((!~x)&&(~y)){
lrm=0;
return -1;
}else if((~x)&&(!~y)){
lrm=1;
return -1;
}
if(x*y>x&&x*y>y){
lrm=2;
if(x*y>MAXFLOW)
return -1;
else
return x*y;
}else if(x>y){
lrm=0;
return x;
}else{
lrm=1;
return y;
}
}else{
if((!~x)&&(!~y)){
lrm=2;
return -1;
}else if((!~x)&&(~y)){
lrm=0;
return -1;
}else if((~x)&&(!~y)){
lrm=1;
return -1;
}
if(x>y){
lrm=0;
return x;
}else{
lrm=1;
return y;
}
}
}
inline void pushup(int x){
t[x].v=getmax(x<<1,x<<1|1,t[x].lrm);
}
void bt(int x,int l,int r){
t[x].l=l,t[x].r=r;
if(l==r){
t[x].v=a[l];
t[x].lrm=2;
return ;
}
int mid=(l+r)>>1;
bt(x<<1,l,mid);
bt(x<<1|1,mid+1,r);
pushup(x);
}
void upd(int x,int k,int w){
if(t[x].l==t[x].r)
return (void)(t[x].v=w);
int mid=(t[x].l+t[x].r)>>1;
if(k<=mid)
upd(x<<1,k,w);
else
upd(x<<1|1,k,w);
pushup(x);
}
int query(int x,int l,int r,int &lrm){
if(l<=t[x].l&&t[x].r<=r){
lrm=2;
return t[x].v;
}
int mid=(t[x].l+t[x].r)>>1,tmp=0,ans=0,tl,tr;
if(l<=mid){
ans=query(x<<1,l,r,tl);
if(tl==0||tl==2)
lrm=0;
else
lrm=3;
}
if(mid<r){
tmp=query(x<<1|1,l,r,tr);
if(!ans){
ans=tmp;
if(tr==1||tr==2)
lrm=1;
else
lrm=3;
}else{
if((!~ans)||(!~tmp)){
ans=-1;
if((!~ans)&&(!~tmp)){
if(tl==2&&tr==2)
lrm=2;
else if(tl==3||tr==3||(tl==1&&tr==0))
lrm=3;
else if(tl==0)
lrm=0;
else
lrm=1;
}else if((!~ans)&&(~tmp)){
if(tl==2||tl==0)
lrm=0;
else
lrm=3;
}else{
if(tr==2||tr==1)
lrm=1;
else
lrm=3;
}
}else{
if(ans*tmp>ans&&ans*tmp>tmp)
if(tl!=3&&tr!=3&&tl!=0&&tr!=1){
ans*=tmp;
if(tl==1&&tr==0)
lrm=3;
else if(tl==2&&tr==2)
lrm=2;
else if(tl==2)
lrm=tr;
else
lrm=tl;
}
else if(ans>tmp){
if(tl==2||tl==0)
lrm=0;
else
lrm=3;
}else{
ans=tmp;
if(tr==2||tr==1)
lrm=1;
else
lrm=3;
}
}
}
}
// cerr<<"at: "<<ans<<" "<<tmp<<'\n';
if(ans>MAXFLOW)
ans=-1;
return ans;
}
signed main(){
cin.tie(nullptr)->sync_with_stdio(false);
cin>>n>>q;
for(int i=1;i<=n;i++)
cin>>a[i];
bt(1,1,n);
for(int i=1,op,x,y,lrm;i<=q;i++){
cin>>op>>x>>y;
if(op==1)
upd(1,x,y);
else{
int k=query(1,x,y,lrm);
if(!~k)
cout<<"Too large\n";
else
cout<<max(1ll,k)<<'\n';
}
}
return 0;
}