没想到贪心,就打了一个暴力。但toolarge好像出问题了。
#include <bits/stdc++.h>
#define lc p*2
#define rc p*2+1
#define int long long
using namespace std;
int n,q;
const int N=2e5+5;
int a[N];
int opt,x,k,l,r;
int f[20];
long long too_large=(1<<30);
struct node{
long long sum,lt=1,lt2=1;
}tr[N<<2];
struct node2{
long long sum,lt;
}tr2[N<<2];
void init(){
f[0]=1;
for(int i=1;i<=18;i++){
f[i]=f[i-1]*2;
}
}
void push_up(int p){
if(tr[lc].sum==-1||tr[rc].sum==-1) tr[p].sum=-1;
else if(tr[lc].sum>too_large/tr[rc].sum) tr[p].sum=-1;
else if(tr[lc].sum==too_large/tr[rc].sum&&too_large%tr[rc].sum!=0) tr[p].sum=-1;
else tr[p].sum=tr[lc].sum*tr[rc].sum;
}
void build(int p,int l,int r){
if(l==r){
tr[p].sum=abs(a[l]);
return ;
}
int m=l+r>>1;
build(lc,l,m);
build(rc,m+1,r);
push_up(p);
}
void push_up2(int p){
tr2[p].sum=tr2[lc].sum+tr2[rc].sum;
}
void build2(int p,int l,int r){
if(l==r){
tr2[p].sum=a[l]<0?1:0;
return ;
}
int m=l+r>>1;
build2(lc,l,m);
build2(rc,m+1,r);
push_up2(p);
}
/*
void push_down(int p,int l,int r){
if(tr[lc].sum>0){
tr[lc].sum*=tr[p].lt2;
tr[lc].sum/=tr[p].lt;
}
if(tr[rc].sum>0){
tr[rc].sum*=tr[p].lt2;
tr[rc].sum/=tr[p].lt;
}
tr[p].lt=tr[p].lt2=1;
}
*/
void upd_chu(int p,int l,int r,int ul,int ur,int k){
if(l>=ul&&r<=ur){
if(tr[p].sum>0) tr[p].sum/=k;
tr[p].lt*=k;
return ;
}
int m=l+r>>1;
if(m>=ul) upd_chu(lc,l,m,ul,ur,k);
if(m+1<=ur) upd_chu(rc,m+1,r,ul,ur,k);
push_up(p);
}
void upd_cheng(int p,int l,int r,int ul,int ur,int k){
if(l>=ul&&r<=ur){
if(tr[p].sum>0){
if(k<too_large/tr[p].sum) tr[p].sum*=k;
else if(k==too_large/tr[p].sum&&too_large%tr[p].sum==0) tr[p].sum*=k;
else tr[p].sum=-1;
}
tr[p].lt2*=k;
return ;
}
int m=l+r>>1;
if(m>=ul) upd_cheng(lc,l,m,ul,ur,k);
if(m+1<=ur) upd_cheng(rc,m+1,r,ul,ur,k);
push_up(p);
}
void upd2(int p,int l,int r,int ul,int ur,int k){
if(l>=ul&&r<=ur){
tr2[p].sum+=k*(r-l+1);
tr2[p].lt+=k;
return ;
}
int m=l+r>>1;
if(m>=ul) upd2(lc,l,m,ul,ur,k);
if(m+1<=ur) upd2(rc,m+1,r,ul,ur,k);
push_up2(p);
}
long long query(int p,int l,int r,int ql,int qr){
if(l>=ql&&r<=qr) return tr[p].sum;
int m=l+r>>1;
long long ans=1;
if(m>=ql){
ans*=query(lc,l,m,ql,qr);
if(ans==-1) return ans;
}
if(m+1<=qr){
int gj=query(rc,m+1,r,ql,qr);
if(gj<too_large/ans) ans*=gj;
else if(gj==too_large/ans&&too_large%ans==0) ans*=gj;
else ans=-1;
if(ans<0) return -1;
}
return ans;
}
long long query2(int p,int l,int r,int ql,int qr){
if(l>=ql&&r<=qr) return tr2[p].sum;
int m=l+r>>1;
int ans=0;
if(m>=ql) ans+=query2(lc,l,m,ql,qr);
if(m+1<=qr) ans+=query2(rc,m+1,r,ql,qr);
return ans;
}
signed main(){
//freopen("T1ex2.in","r",stdin);
//freopen("18.out","w",stdout);
cin>>n>>q;
for(int i=1;i<=n;i++)
cin>>a[i];
build(1,1,n);
build2(1,1,n);
init();
while(q--){
scanf("%d",&opt);
if(opt==1){
scanf("%d%d",&x,&k);
if(k<0){
if(a[x]>0) upd2(1,1,n,x,x,1);
}
if(k>0){
if(a[x]<0) upd2(1,1,n,x,x,-1);
}
upd_chu(1,1,n,x,x,abs(a[x]));
upd_cheng(1,1,n,x,x,abs(k));
a[x]=k;
}
else{
scanf("%d%d",&l,&r);
if(query2(1,1,n,l,r)%2==0){
int sum=query(1,1,n,l,r);
if(sum==-1) printf("Too large\n");
else printf("%lld\n",sum);
}
else if(l==r){
cout<<1<<endl;
}
else{
int step=l,com=query2(1,1,n,l,r),sum,sum2;
for(int i=18;i>=0;i--){
if(step+f[i]<=r&&query2(1,1,n,step+f[i],r)==com)
step+=f[i];
}
step++;
sum=query(1,1,n,step,r);
step=r;
for(int i=18;i>=0;i--){
if(step-f[i]>=l&&query2(1,1,n,l,step-f[i])==com)
step-=f[i];
}
step--;
sum2=query(1,1,n,l,step);
if(sum==-1||sum2==-1){
printf("Too large\n");
}
else printf("%lld\n",max(sum,sum2));
}
}
}
}