Hdu 5696 区间价值(2016百度之星初赛Astar Round2B )(线段树)
Posted WangFeng
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hdu 5696 区间价值(2016百度之星初赛Astar Round2B )(线段树)相关的知识,希望对你有一定的参考价值。
思路来源于:http://blog.csdn.net/kk303/article/details/51479423
注意数组用 long long 存,否则WA。
/* Problem : Status : By wf, */ #include "algorithm" #include "iostream" #include "cstring" #include "cstdio" #include "string" #include "stack" #include "cmath" #include "queue" #include "set" #include "map" #define lson l , m , rt << 1 #define rson m + 1 , r , rt << 1 | 1 typedef long long ll; using namespace std; const int inf=0x3f3f3f3f; const int maxn=1e5+5; int Tmin[ maxn << 2 ]; int Tmax[ maxn << 2 ]; ll A[maxn]; int n; ll ans [maxn]; int index; void min_push_up(int rt) { if( A[ Tmin[rt<<1] ] < A[ Tmin[rt<<1|1] ] ) { Tmin[rt] = Tmin[rt<<1]; } else Tmin[rt] = Tmin[rt<<1|1]; } void min_build(int l,int r,int rt) { if( l==r ) { Tmin[rt] = index++; return; } int m =(l+r)>>1; min_build(lson); min_build(rson); min_push_up(rt); } int min_query(int L,int R,int l,int r,int rt) { if( L <= l && r <= R ) { return Tmin[rt]; } int m = (l+r)>>1; int ret1 = -1,ret2=-1; if( L<=m ) ret1 = min_query(L,R,lson); if( R>m )ret2 = min_query(L,R,rson); if( ret1==-1 )return ret2; if( ret2==-1 )return ret1; if(A[ret1] > A[ret2] )return ret2; return ret1; } //************************************************** void max_push_up(int rt) { if( A[ Tmax[rt<<1] ] >= A[ Tmax[rt<<1|1] ] ) { Tmax[rt] = Tmax[rt<<1]; } else Tmax[rt] = Tmax[rt<<1|1]; } void max_build(int l,int r,int rt) { if( l==r ) { Tmax[rt] = index++; return; } int m =(l+r)>>1; max_build(lson); max_build(rson); max_push_up(rt); } int max_query(int L,int R,int l,int r,int rt) { if( L <= l && r <= R ) { return Tmax[rt]; } int m = (l+r)>>1; int ret1 = -1 , ret2 = -1; if( L<=m ) ret1 = max_query(L,R,lson); if( R>m )ret2 = max_query(L,R,rson); if( ret1==-1 )return ret2; if( ret2==-1 )return ret1; if(A[ret1] < A[ret2] )return ret2; return ret1; } // main code void dfs(int l,int r,int n) { if( r<l )return; int a = max_query(l,r,1,n,1); int b = min_query(l,r,1,n,1); if(a>b)swap(a,b); ll d = A[a] * A[b]; //printf("a==%d,b==%d,d==%I64d\n",a,b,d); for(int i = (b-a+1);i<=(r-l+1);++i ) { ans[i] = max( ans[i],d ); //printf( "[%d,%d] ans[%d] = %I64d (%d * %d)\n",l,r,i,ans[i],a,b); } if(A[b]>A[a]) { dfs(a+1,r,n); dfs(l,a-1,n); } else { dfs(b+1,r,n); dfs(l,b-1,n); } } int main() { //freopen("in.txt","r",stdin); while( scanf("%d",&n)!=EOF ) { memset(Tmin,0,sizeof Tmin); memset(Tmax,0,sizeof Tmax); for(int i=1;i<=n;++i) { scanf("%I64d",&A[i]); } //init memset(ans,0,sizeof ans); index = 1; min_build(1,n,1); index = 1; max_build(1,n,1); dfs(1,n,n); for(int i=1;i<=n;++i) { printf("%I64d\n",ans[i]); } //printf("Min:%d\n",min_query(1,n,1,n,1)); //printf("Max:%d\n",max_query(1,n,1,n,1)); } return 0; }
以上是关于Hdu 5696 区间价值(2016百度之星初赛Astar Round2B )(线段树)的主要内容,如果未能解决你的问题,请参考以下文章
ACM学习历程—HDU5696 区间的价值(分治 && RMQ && 线段树 && 动态规划)
2016"百度之星" - 初赛(Astar Round2B)
hdu 5698 瞬间移动(2016"百度之星" - 初赛(Astar Round2B)——数学题)