Educational Codeforces Round 35
E. Stack Sorting
题意:长度为 n 的序列 a[] ,a[] 里的数是 1~n,一个空栈 s,一个空序列 b[]。两个操作:把 a[] 的第一个数放到 s 里; 或者把 s 的栈顶元素加到 b[] 的末尾。
如果你能通过这两个操作把 a[] 的数最后都放入 b[] 中,且 b[] 是升序的,那就可说 a[] 是 stack-sortable 。
现在给出 a[] 的前 k 个数,要你确定是否有满足 stack-sortable 条件的 a[] 。如果有,输出字典序最大的。
tags:好苟的题。。
其实大体的思路很好想,就是 a[] 里会出现 " 中 、大、小 " 这样顺序的就是不可能。
但最苟的是后面 n-k 个数应该怎么输出,这里挖了好几发。。。
把前 k 个数从小到大排序后,变为 a1, a2, ...... ak 。 后面 n-k 个数,先输出 a1->1,再是 a2 -> a1, 再是 a3->a2, a4->a3 ........,ak -> a(k-1), n -> ak 。
#include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define rep(i,a,b) for (int i=a; i<=b; ++i) #define per(i,b,a) for (int i=b; i>=a; --i) #define mes(a,b) memset(a,b,sizeof(a)) #define INF 0x3f3f3f3f #define MP make_pair #define PB push_back #define fi first #define se second typedef long long ll; const int N = 200005; int n, k, p[N], mi[N], bit[N]; bool vis[N]; void Add(int x, int y) { for(int i=x; i<N; i+=i&-i) bit[i] += y; } int Sum(int x) { int ans = 0; for(int i=x; i>0; i-=i&-i) ans += bit[i]; return ans; } int main() { mes(mi, INF); scanf("%d%d", &n, &k); int mm = INF, mx = 0; rep(i,1,k) { scanf("%d", &p[i]); vis[p[i]]=true; mm = min(mm, p[i]); mx = max(mx, p[i]); } mi[k] = p[k]; rep(i,1,n) if(!vis[i]) { mi[k] = min(mi[k], i); mi[k+1] = i; break; } per(i,k-1,1) mi[i] = min(mi[i+1], p[i]); Add(p[1], 1); rep(i,2,k) { Add(p[i], 1); int tmp = Sum(p[i]-1) - Sum(mi[i+1]); if(tmp > 0) return 0*printf("-1\n"); } rep(i,1,k) printf("%d ", p[i]); sort(p+1, p+1+k); per(j,p[1]-1,1) printf("%d ", j); rep(i,1,k-1) { per(j,p[i+1]-1,p[i]+1) printf("%d ", j); } per(j,n,p[k]+1) printf("%d ", j); return 0; }