hdu 3410(单调队列)
2015-01-10 10:08
302 查看
题意:
给出一个数组a[],问你对于第i个数,从最后一个比它大的数到它之间比它小的数中最大的那个数的下标,以及它右边到第一个比它大的数中比它小的数中最大的那一个数的下标<下标从1开始>。
eg:a[]= 5 2 4 3 1
left 0 0 2 0 0 对5来说左边比它小的数没有,所以是0。对2来说左边比它小的数没有,所以是0。对4来说左边比它小的数是2,所以下标是2。
right 3 0 4 5 0 对5来说右边比它小的数中最大的是4,是第3个,所以答案是3。对2来说右边比它小的数是1,但是4比2大,所以无法到达1,所以答案是0。对于4,右边比它小的数中最大一个3的下标是4,所以答案是4。
分析:以左区间为例,若当前查询的数是a[i],则要求出满足条件的左区间内的最大值,而求区间最大值的话容易想到单调队列。维护一个单调递减队列,将a[i]入队,若队尾有元素出队,则最后一个出队的就是所求区间最大值(这点很好明白,队列是递减的,那么越晚出去的数就越大);若没有元素出队,则说明满足条件的左区间不存在,存入0就行了。
求右区间的过程与左区间一样,只不过要把数组逆着入队。
代码如下:
给出一个数组a[],问你对于第i个数,从最后一个比它大的数到它之间比它小的数中最大的那个数的下标,以及它右边到第一个比它大的数中比它小的数中最大的那一个数的下标<下标从1开始>。
eg:a[]= 5 2 4 3 1
left 0 0 2 0 0 对5来说左边比它小的数没有,所以是0。对2来说左边比它小的数没有,所以是0。对4来说左边比它小的数是2,所以下标是2。
right 3 0 4 5 0 对5来说右边比它小的数中最大的是4,是第3个,所以答案是3。对2来说右边比它小的数是1,但是4比2大,所以无法到达1,所以答案是0。对于4,右边比它小的数中最大一个3的下标是4,所以答案是4。
分析:以左区间为例,若当前查询的数是a[i],则要求出满足条件的左区间内的最大值,而求区间最大值的话容易想到单调队列。维护一个单调递减队列,将a[i]入队,若队尾有元素出队,则最后一个出队的就是所求区间最大值(这点很好明白,队列是递减的,那么越晚出去的数就越大);若没有元素出队,则说明满足条件的左区间不存在,存入0就行了。
求右区间的过程与左区间一样,只不过要把数组逆着入队。
代码如下:
#include<cstdio> #include<cstring> #include<iostream> #include<cstdlib> #include<cmath> #include<algorithm> #include<queue> #include<stack> #include<set> #include<map> using namespace std; typedef long long ll; const int M=1010; const int N=50010; const int INF=1e9; const double PI=acos(-1.0); const double Exp=exp(1.0); int n,m,a ; int main() { int i,j,t,kk=1; scanf("%d",&t); while(t--) { scanf("%d",&n); pair<int,int> p ; for (i=1;i<=n;i++) scanf("%d",a+i); int q ,head=0,tail=0,ans=0; for (i=1;i<=n;i++){ // 左区间 ans=0; while(head<tail && a[q[tail-1]]<=a[i]) { ans=q[tail-1]; tail--; } q[tail++]=i; p[i].first=ans;// cout<<"ans="<<ans<<endl; //while(head<tail && ) } head=0,tail=0,ans=0; for (i=n;i>0;i--) { <span style="font-family: Verdana, Arial, Helvetica, sans-serif;">// 右区间</span> ans=0; while(head<tail && a[q[tail-1]]<=a[i]) { ans=q[tail-1]; tail--; } q[tail++]=i; p[i].second=ans; } printf("Case %d:\n",kk++); for (i=1;i<=n;i++) { printf("%d %d\n",p[i].first,p[i].second); } } }
相关文章推荐
- HDU 3410 && POJ 3776 Passing the Message 单调队列
- hdu~3410(单调队列)
- Hdu 3410 【单调队列】.cpp
- HDU 3410 && POJ 3776 Passing the Message 单调队列
- hdu-3410 Passing the Message[单调队列]
- hdu 3410(单调队列)
- hdu 3410 Passing the Message(单调队列)
- hdu 3415 Max Sum of Max-K-sub-sequence(单调队列)
- hdu 4193 Non-negative Partial Sums 单调队列
- hdu 1506#单调队列
- HDU 4374 One hundred layer(单调队列+DP)
- HDU1171 单调队列优化多重背包O(VN)
- 单调队列的一个应用——求解连续区间最大值(HDU Max Sum of Max-K-sub-sequence)
- HDU 4193 Non-negative Partial Sums(单调队列)
- hdu 3415 Max Sum of Max-K-sub-sequence 单调队列 求连续l(1<=l<=k)个数的和的最大值 数列可循环
- hdu 3415 单调队列1
- hdu 3530 Subsequence 单调队列 求最长连续区间,满足条件(m<=max-min<=k)
- HDU 1003——Max Sum (单调队列做法)
- hdu Max Sum of Max-K-sub-sequence 单调队列优化DP
- hdu Max Sum of Max-K-sub-sequence(单调队列)