pre[x][1/2] 表示正/负前缀
tail[x][1/2] 表示正/负后缀
sum[x] 表示区间乘
tmax[x] 表示区间最大值
#include<bits/stdc++.h>
#define lc k << 1
#define rc k << 1 | 1
#define lcon lc , l , mid
#define rcon rc , mid + 1 , r
#define Mid int mid = (l + r) >> 1
#define f(i , a , b) for(int i = a;i <= b;i++)
#define t(i , a , b) for(int i = a;i >= b;i--)
#define N 2500003
using namespace std;
struct node{
long long pl[3] , tl[3];
long long sm;
long long tmx;
};
int n;
long long a[N];
long long tmax[N << 2] , pre[N << 2][3] , tail[N << 2][3] , sum[N << 1];
void pushup(int k) {
/*tmax[k] = 0;
pre[k][1] = tail[k][1] = pre[k][2] = tail[k][2] = 1;
sum[k] = 1;*/
tmax[k] = max(tmax[lc] , tmax[rc]);
tmax[k] = max(tmax[k] , tail[lc][1] * pre[rc][1]);
tmax[k] = max(tmax[k] , tail[lc][2] * pre[rc][2]);
pre[k][1] = pre[lc][1];
pre[k][2] = pre[lc][2];
tail[k][1] = tail[rc][1];
tail[k][2] = tail[rc][2];
if(sum[lc] > 0)
pre[k][1] = max(pre[k][1] , sum[lc] * pre[rc][1]);
else
pre[k][1] = max(pre[k][1] , sum[lc] * pre[rc][2]);
if(sum[lc] > 0)
pre[k][2] = min(pre[k][2] , sum[lc] * pre[rc][2]);
else
pre[k][2] = min(pre[k][2] , sum[lc] * pre[rc][1]);
if(sum[rc] > 0)
tail[k][1] = max(tail[k][1] , sum[rc] * tail[lc][1]);
else
tail[k][1] = max(tail[k][1] , sum[rc] * tail[lc][2]);
if(sum[rc] > 0)
tail[k][2] = min(tail[k][2] , sum[rc] * tail[lc][2]);
else
tail[k][2] = min(tail[k][2] , sum[rc] * tail[lc][1]);
sum[k] = sum[lc] * sum[rc];
}
void build(int k,int l , int r) {
pre[k][1] = tail[k][1] = pre[k][2] = tail[k][2] = 1;
if(l == r) {
tmax[k] = a[l];
sum[k] = a[l];
if(a[l] > 0) pre[k][1] = tail[k][1] = a[l];
else pre[k][2] = tail[k][2] = a[l];
return;
}
Mid;
build(lcon) , build(rcon);
pushup(k);
}
void update(int k , int l ,int r , int x , int v) {
if(l == r && l == x) {
pre[k][1] = tail[k][1] = pre[k][2] = tail[k][2] = 1;
tmax[k] = v;
sum[k] = v;
if(v > 0) pre[k][1] = tail[k][1] = v;
else pre[k][2] = tail[k][2] = v;
return;
}
Mid;
if(x <= mid) update(lcon , x , v);
else update(rcon , x , v);
pushup(k);
}
node query(int k , int l , int r , int x , int y) {
node ans;
if(x <= l && r <= y) {
ans.pl[1] = pre[k][1];
ans.pl[2] = pre[k][2];
ans.tl[1] = tail[k][1];
ans.tl[2] = tail[k][2];
ans.sm = sum[k];
ans.tmx = tmax[k];
return ans;
}
Mid;
if(x <= mid && y > mid) {
ans = query(lcon , x , y);
node ans2 = query(rcon , x , y) , Ans;
Ans.tmx = max(ans.tmx , ans2.tmx);
Ans.tmx = max(Ans.tmx , ans.tl[1] * ans2.pl[1]);
Ans.tmx = max(Ans.tmx , ans.tl[2] * ans2.pl[2]);
Ans.pl[1] = ans.pl[1];
Ans.pl[2] = ans.pl[2];
Ans.tl[1] = ans2.tl[1];
Ans.tl[2] = ans2.tl[2];
if(ans.sm > 0)
Ans.pl[1] = max(Ans.pl[1] , ans.sm * ans2.pl[1]);
else
Ans.pl[1] = max(Ans.pl[1] , ans.sm * ans2.pl[2]);
if(sum[lc] > 0)
pre[k][2] = min(pre[k][2] , ans.sm * ans2.pl[2]);
else
pre[k][2] = min(pre[k][2] , ans.sm * ans2.pl[1]);
if(ans2.sm > 0)
Ans.tl[1] = max(Ans.tl[1] , ans2.sm * ans.tl[1]);
else
Ans.tl[1] = max(Ans.tl[1] , ans2.sm * ans.tl[2]);
if(ans2.sm > 0)
Ans.tl[2] = min(Ans.tl[2] , ans2.sm * ans.tl[2]);
else
Ans.tl[2] = min(Ans.tl[2] , ans2.sm * ans.tl[1]);
Ans.sm = ans.sm * ans2.sm;
return Ans;
}
else if(x <= mid) return query(lcon , x , y);
else if(y > mid) return query(rcon , x , y);
}
int Q;
int main() {
ios::sync_with_stdio(0);
cin >> n >> Q;
f(i , 1 , n) cin >> a[i];
build(1 , 1 , n);
//f(i , 1 , n) f(j , i , n) printf("l:%d r:%d ans:%lld preN:%lld tailN:%lld preZ:%lld tailZ:%lld\n" , i , j , query(1 , 1 , n , i , j).tmx , query(1 , 1 , n , i , j).pl[1] , query(1 , 1 , n , i , j).tl[1] , query(1 , 1 , n , i , j).pl[2] , query(1 , 1 , n , i , j).tl[2]);
while(Q--) {
int x , y , z;
cin >> x >> y >> z;
if(x == 1) {
update(1 , 1 , n , y , z);
/*cout << " \n";
f(i , 1 , n) f(j , i , n) printf("l:%d r:%d ans:%lld \n" , i , j , query(1 , 1 , n , i , j).tmx);
cout << "\n ";*/
} else {
//cout << y << " " << z << " ";
node ans = query(1 , 1 , n , y , z);
long long answer = max(ans.tmx , max(ans.pl[1] , ans.tl[1]));
if(answer > 1073741824) cout << "Too large\n";
else cout << max(answer , (long long)1) << "\n";
}
}
/*cout << " \n";
f(i , 1 , n) f(j , i , n) printf("l:%d r:%d ans:%lld \n" , i , j , query(1 , 1 , n , i , j).tmx);
cout << "\n ";*/
return 0;
}