题目:http://acm.split.hdu.edu.cn/showproblem.php?pid=6215
题意:给定一个序列,每次删除序列中所有在下滑趋势中的点,问最后剩下的序列
设置一个队列,将可能产生下滑趋势的点放入
每次取出数时,如果被删除了,则将它前面一个点放入队列
#include<cstdio> #include<iostream> #include<cmath> #include<queue> #include<map> #include<set> #include<stack> #include<stack> #include<string> #include<sstream> #include<cstring> #include<algorithm> using namespace std; const int N=1e5; int nextt[N+5],last[N+5],a[N+5],que[N+5]; int main() { int T; scanf("%d",&T); while(T--) { int n; scanf("%d",&n); int ans=n; a[0]=0; nextt[0]=1; last[n+1]=n; int top=0; for(int i=1;i<=n;i++) { scanf("%d",&a[i]); nextt[i]=i+1; last[i]=i-1; que[top++]=i; } int flag=1; while(flag) { flag=0; int s=0; int now=0; while(now<top) { int i=que[now],f=0; while(nextt[i]<=n) { if (a[i]>a[nextt[i]]) { f++; i=nextt[i]; flag=1; } else break; } if (f) { ans-=(f+1); nextt[last[que[now]]]=nextt[i]; last[nextt[i]]=last[que[now]]; que[s++]=last[que[now]]; } while(que[now]<=i&&now<top) now++; } top=s; } printf("%d ",ans); int now=nextt[0]; while(now<=n) { printf("%d ",a[now]); now=nextt[now]; } printf(" "); } return 0; }