HDU5696:区间的价值——题解

http://acm.hdu.edu.cn/showproblem.php?pid=5696

题面是中文的我就不粘贴过来了……

————————————————————————

这题垃圾题!!神tm卡常数,搞得我最后跟AC代码对了半天才过……

因为是随机数据,所以我们完全可以二分区间,查找当前区间的最大值,然后求出所有包含这个最大值的区间的价值,并且更新,然后将这个最大值左右两个区间递归处理即可。

但是真的这么垃圾题很容易卡常数啊……

#include<cmath>
#include<cctype>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=100001;
inline int read(){
    int X=0,w=0;char ch=0;
    while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
    while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
    return w?-X:X;
}
ll a[N],ans[N],t[N];
void solve(int l,int r){
    if(l>r)return;
    int p=0;
    for(int i=l;i<=r;i++){
    if(!p||a[i]<a[p])p=i;
    }
    int w=r-l+1;
    for(int i=1;i<=w;i++)t[i]=0;
    for(int i=l;i<=p;i++)t[p-i+1]=max(t[p-i+1],a[p]*a[i]);
    for(int i=p;i<=r;i++)t[i-p+1]=max(t[i-p+1],a[p]*a[i]);
    ll maxn=0;
    for(int i=1;i<=w;i++){
    maxn=max(maxn,t[i]);
    ans[i]=max(ans[i],maxn);
    }
    solve(l,p-1);solve(p+1,r);
    return;
}
int main(){
    int n;
    while(scanf("%d",&n)!=EOF&&n){
    memset(ans,0,sizeof(ans));
    for(int i=1;i<=n;i++){
        a[i]=read();
    }
    solve(1,n);
    for(int i=1;i<=n;i++)printf("%lld
",ans[i]);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/luyouqi233/p/8032774.html