首页 > 其他 > 详细

[补]2019HDU杭电多校第二场B

时间:2019-08-04 18:00:42      阅读:57      评论:0      收藏:0      [点我收藏+]

补得甚是艰辛

-如非必要,不用STL-患者红小豆上线

参考于:https://www.cnblogs.com/Dillonh/p/11240083.html(为了两个continue还在评论区叨扰了一下,多次试验之后似乎有点明白,趁没被注意偷偷删掉:P)

 

 

HDU-6592 Beauty of  unimodal sequence

  调完了诸如中括号里打了另一个数组的下标之类的bug之后,最大的wa点是dp数组大小少打个0

  const xx maxn 一个错全都错,还是每个数组打一次大小 一个错错一个,这是一个问题_(:з」∠)_

  输出格式好要命啊啊啊wa之后还来了发PE

  正文:首先对序列正着跑一边LIS,再反着跑一遍,分别记录下标(ppo-positive,opo-over:P)顺便给po初始化一下;

     原blog开了两个vector,小可寻思着一个数组(叫v吧)加个下标变量就可以复用。

     task1  字典序最小下标序列--开始找峰,字典序最小,所以一旦找到,就用这个。接着开始从峰向前找尽量靠前的同LIS下标的数,看了原blog第一个continue的条件,感觉不会有那种情况,然后就得寸进尺地(x)想去掉第二个continue,然而第二个是有去重作用的_(:з」∠)_查了好久的输出文件突然察觉到这个问题。前面查完了再查后面,后面的部分就是只要符合条件就拿,这样下标最小。stack和v倒腾一下输出就完事了。

     task 2 字典序最大下标序列--开始找峰,找到尽量靠后的那个峰,顺手重新初始化po。往前找,找到就拿,这样下标最大。往后找,(一个迷之懒得用reverse的红小豆就用v模拟了一个stack)进行和task1里的前半部分类似的操作。输出完事。

  细节见码

技术分享图片
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<stack>
using namespace std;
typedef long long LL;
int n;
int num[300005], ppo[300005], opo[300005], v[300005], d[300005], po[300005];
stack<int>sa;

int main()
{
    while (~scanf("%d", &n)) {

        memset(d, 0x3f, sizeof d);
        d[0] = 0;
        for (int i = 1; i <= n; i++) {
            scanf("%d", &num[i]);
            ppo[i] = lower_bound(d + 1, d + 1 + n, num[i]) - d;
            d[ppo[i]] = num[i];
            po[i] = 0x3f3f3f3f;
        }
        memset(d, 0x3f, sizeof d);
        d[0] = 0;
        for (int i = n; i >= 1; i--) {
            opo[i] = lower_bound(d + 1, d + 1 + n, num[i]) - d;
            d[opo[i]] = num[i];
        }


        int co = 0;
        int now = 1, m = ppo[1] + opo[1];
        for (int i = 2; i <= n; i++)
            if (ppo[i] + opo[i] > m) { now = i; m = opo[i] + ppo[i]; }
        po[ppo[now]] = num[now];
        for (int i = now - 1; i >= 1; i--) {
            if (po[ppo[i] + 1] <= num[i]) continue;
            while (!sa.empty() && ppo[i] >= ppo[sa.top()])po[ppo[sa.top()]] = 0x3f3f3f3f, sa.pop();
            sa.push(i);
            po[ppo[i]] = num[i];
        }
        while (!sa.empty()) v[co++] = sa.top(), sa.pop();
        v[co++] = now;
        for (int i = now + 1; i <= n; i++)
            if (opo[i] == opo[v[co - 1]] - 1 && num[i] < num[v[co - 1]])v[co++] = i;
        for (int i = 0; i < co; i++)printf("%d%c", v[i], " \n"[i == co - 1]);


        co = 0;
        now = 1; m = ppo[1] + opo[1]; po[1] = 0x3f3f3f3f;
        for (int i = 2; i <= n; i++) {
            if (ppo[i] + opo[i] >= m) { now = i; m = opo[i] + ppo[i]; }
            po[i] = 0x3f3f3f3f;
        }
        sa.push(now);
        for (int i = now - 1; i >= 1; i--)
            if (ppo[i] == ppo[sa.top()] - 1 && num[i] < num[sa.top()])sa.push(i);
        while (!sa.empty())v[co++] = sa.top(), sa.pop();
        po[opo[now]] = num[now];
        for (int i = now + 1; i <= n; i++) {
            if (num[i] >= po[opo[i] + 1]) continue;
            while (co && opo[i] >= opo[v[co - 1]])po[opo[v[co - 1]]] = 0x3f3f3f3f, co--;
            v[co++] = i;
            po[opo[i]] = num[i];
        }
        for (int i = 0; i < co; i++)printf("%d%c", v[i], " \n"[i == co - 1]);
    }

    return 0;
}
Beauty of unimodal sequence

 

  (新建之前想着还有什么要写来着但是忘了。。想起来再说)

 

[补]2019HDU杭电多校第二场B

原文:https://www.cnblogs.com/non-/p/11298904.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!