2021牛客多校 Stack(思维+构造)

本文介绍了一种通过单调栈实现的高效算法,用于解决给定部分b数组并还原a数组的问题。作者分享了错误思路后的正确解法,包括线段树维护区间第k小元素,并展示了如何用C++代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

**题意:**单调栈中先放数,然后计算出栈的大小存入b数组。现在给你b的部分数组,然后让你还原出一种a数组。
题解:

  1. 一开始我想了个假算法,把队友带飞了
  2. 我们从1-n开始构造b数组,如果没有给定b,则直接插入到当前栈中,及b[i] = b[i-1] + 1
  3. 并且根据b数组单调的关系,我们可知b[i] > b[i-1] + 1 的话,这样就中间肯定没有足够的数字进行填充,所以直接输出-1
  4. 我是写了个线段树维护区间第k小,然后取出,这样来进行构造a数组
    code:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i, a, n) for (int i = a; i <= n; i++)
#define per(i, a, n) for (int i = n; i >= a; i--)
#define lowbit(x) ((x) & -(x))
#define lson p << 1, l, mid
#define rson p << 1 | 1, mid + 1, r
#define mem(a, b) memset(a, b, sizeof(a))
#define IOS                      \
    ios::sync_with_stdio(false); \
    cin.tie(0);                  \
    cout.tie(0);

const int N = 1e6 + 50;
int ans[N];
bool flag = 0;
int n, k;
bool vis[N];
queue<int> que;

struct node
{
    int pos, x;
} e[N];


struct tree
{
    int l, r;
    int cnt;
} t[N << 2];

struct sj
{
    int id;
    int num;
} b[N];

void build(int l, int r, int p)
{
    t[p] = {l, r, 0};
    if (l == r)
    {
        t[p].cnt = 1;
        return;
    }
    int mid = l + r >> 1;
    build(l, mid, p << 1);
    build(mid + 1, r, p << 1 | 1);
    t[p].cnt = t[p << 1].cnt + t[p << 1 | 1].cnt;
}

int ask(int l, int r, int p, int k)
{
    if (t[p].l == t[p].r)
    {
        return t[p].l;
    }
    if (k <= t[p << 1].cnt)
        return ask(l, r, p << 1, k);
    else
        return ask(l, r, p << 1 | 1, k - t[p << 1].cnt);
}

void modify(int pos, int p)
{
    if (t[p].l == t[p].r)
    {
        t[p].cnt = 0;
        return;
    }
    int mid = t[p].l + t[p].r >> 1;
    if (pos <= mid)
        modify(pos, p << 1);
    else
        modify(pos, p << 1 | 1);
    t[p].cnt = t[p << 1 | 1].cnt + t[p << 1].cnt;
}

void solve()
{
    build(1, n, 1);
    for (int i = n; i >= 1; i--)
    {
        int p = b[i].id, x = b[i].num;
        int tmp = ask(1, n, 1, x);
        vis[tmp] = 1;
        ans[p] = tmp;
        modify(tmp, 1);
    }
    rep(i, 1, n) cout << ans[i] << " ";
}

int main()
{
    IOS cin >> n >> k;
    rep(i, 1, k)
    {
        cin >> e[i].pos >> e[i].x;
        b[e[i].pos].num = e[i].x;
    }
    for (int i = 1; i <= n; i++)
    {
        b[i].id = i;
        if (b[i].num)
        {
            if (b[i].num > b[i - 1].num + 1)
            {
                printf("-1\n");
                return 0;
            }
        }
        else
            b[i].num = b[i - 1].num + 1;
    }
    solve();
    return 0;
}
### 关于洛谷和平台上的C++编译器G++和Clang使用区别 #### 平台支持的编译器版本差异 洛谷和网作为在线编程学习与竞赛平台,均提供了种C++编译器供用户选择。通常情况下,默认选项为G++编译器[^1]。 对于G++而言,在线评测系统倾向于采用较新版本以兼容更现代C++特性;而Clang则以其快速编译速度以及友好的错误提示著称,部分开发者更偏好于此款编译工具。 #### 编译参数设置的不同之处 当涉及到具体编译参数设定时,两个平台可能存在细微差别: - **标准库的选择** - G++一般会依据其内置配置自动选用适当的标准库版本。 - Clang可能允许更加灵活地指定标准库路径或版本号[^3]。 - **优化级别(-O标志)** - 大数情况下,默认启用-O2级别的优化来平衡执行效率与编译时间。 - **警告等级及其他附加选项** - 可能存在一些特定于某个平台的安全检查或其他辅助功能开关被开启的情况,比如`-Wsign-compare`, `-Wc++11-extensions`等用于增强代码质量检测的能力。 #### 实际应用中的表现对比 考虑到判题系统的特殊需求——即高效准确地完成程序验证工作,因此无论是在洛谷还是上运行相同源码的结果应当保持一致。然而由于底层实现机制的不同(如GCC基于GNU项目框架构建而成,而LLVM/Clang旨在提供一种模块化架构),某些极端条件下可能会观察到性能方面的小幅波动或是报错信息格式有所变化。 为了确保跨平台的一致性和稳定性,建议参赛者们熟悉并测试自己惯用的开发环境下的编译方式,并在正式提交之前利用目标平台提供的调试资源进行充分预演。 ```cpp // 示例:定义一个简单的函数计算斐波那契数列第n项 #include <iostream> using namespace std; long long fibonacci(int n){ if(n<=1)return n; else return fibonacci(n-1)+fibonacci(n-2); } int main(){ cout << "Fib(10)=" << fibonacci(10) << endl; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值