Educational Codeforces Round 35 E. Stack Sorting 模拟

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
");
    }
    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;
}
原文地址:https://www.cnblogs.com/sbfhy/p/8146545.html