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\n",ans[i]); } return 0; }