1128 - 咸鱼拷问
Time Limit:3s Memory Limit:128MByte
Submissions:360Solved:107
DESCRIPTION
给你两个序列A,B。每个序列有N个元素,我们定义第i个位置的咸鱼值为min(A[i],A[i-1]…A[i-B[i]+1])*max(A[i],A[i-1]….A[i-B[i]+1]).。
现在咸鱼王想知道所有的咸鱼值,于是抓住了你,让你回答这道题。
你能回答他吗?
INPUT
第一行包括一个整数N(1<=N<=1e5)第二行包括N个整数,表示为A[i] (|A[i]| <= 10^9)第三行包括N个整数,表示为B[i] ( 1 <= B[i] <= i)
OUTPUT
输出N行,第i行表示第i个咸鱼值。
SAMPLE INPUT
51 2 3 4 51 2 1 2 3
SAMPLE OUTPUT
1291215
SOLUTION
题解:
线段树模板题, 错了几次, 忽略了 最后的积会爆int 还忽略了 最小值有负值。
#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 max(int x,int y){
if(x>y) return x;
return y;
}
int min(int x,int y){
if(x<y) return x;
return y;
}
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;
}