题目链接:hdu 3410 Passing the Message
题意:
说那么多,其实就是对于每个a[i],让你找他的从左边(右边)开始找a[j]<a[i]并且a[j]=max(a[j])(k+1<j<i),a[k]>a[i]。
题解:
从左往右维护一个递减的单调队列,每次都从尾巴开始把比a[i]的踢掉,最后踢的那个就是答案。
右边同理。
1 #include<bits/stdc++.h> 2 #define F(i,a,b) for(int i=a;i<=b;i++) 3 using namespace std; 4 5 const int N=5e4+7; 6 int t,n,a[N],Q[N],ans1[N],ans2[N],head,tail,ic; 7 8 int main() 9 { 10 scanf("%d",&t); 11 while(t--) 12 { 13 scanf("%d",&n); 14 F(i,1,n)scanf("%d",a+i); 15 head=1,tail=0; 16 F(i,1,n) 17 { 18 int flag=0; 19 while(head<=tail&&a[Q[tail]]<a[i])tail--,flag=1; 20 if(flag)ans1[i]=Q[tail+1];else ans1[i]=0; 21 Q[++tail]=i; 22 } 23 head=1,tail=0; 24 for(int i=n;i>0;i--) 25 { 26 int flag=0; 27 while(head<=tail&&a[Q[tail]]<a[i])tail--,flag=1; 28 if(flag)ans2[i]=Q[tail+1];else ans2[i]=0; 29 Q[++tail]=i; 30 } 31 printf("Case %d: ",++ic); 32 F(i,1,n)printf("%d %d ",ans1[i],ans2[i]); 33 } 34 return 0; 35 }