线段树维护区间最大最小值即可。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int maxn = 1e5+100;
const int inf=1e17;
int n;
int b[maxn];
int mx[maxn<<2],mi[maxn<<2];
void pushup(int rt){
mx[rt]=max(mx[rt<<1],mx[rt<<1|1]);
mi[rt]=min(mi[rt<<1],mi[rt<<1|1]);
}
void build(int l,int r,int rt){
if(l==r){
scanf("%d",&mx[rt]);
mi[rt]=mx[rt];
return ;
}
int m=(l+r)>>1;
build(lson);
build(rson);
pushup(rt);
}
ll query1(int L,int R,int l,int r,int rt){
if(L<=l&&r<=R) return mx[rt];
int m=(l+r)>>1;
ll ret=-inf;
if(L<=m) ret=max(ret,query1(L,R,lson));
if(R>m) ret=max(ret,query1(L,R,rson));
return ret;
}
ll query2(int L,int R,int l,int r,int rt){
if(L<=l&&r<=R) return mi[rt];
int m=(l+r)>>1;
ll ret=inf;
if(L<=m) ret=min(ret,query2(L,R,lson));
if(R>m) ret=min(ret,query2(L,R,rson));
return ret;
}
int main(){
scanf("%d",&n);
build(1,n,1);
for(int i=1;i<=n;++i) scanf("%d",&b[i]);
for(int i=1;i<=n;++i){
ll ans=query1(i-b[i]+1,i,1,n,1)*query2(i-b[i]+1,i,1,n,1);
printf("%lld\n",ans);
}
return 0;
}