题目链接

传送门

思路

首先我们对\(a\)正反各跑一边\(LIS\),记录每个位置在前一半的\(LIS\)中应该放的位置\(ans1[i]\),后一半的位置\(ans2[i]\)。

对于字典序最小的方案,我们找到第一个峰值,然后往前遍历。在\(i\)这个位置,如果它在\(LIS\)中放的位置是\(pos\),那么我们先看当前放在\(pos+1\)的值是否比它大,大的话就说明这个位置一定比前面放过在\(pos\)这个位置的更优(因为字典序更小,且\([1,i]\)一定可以放满\([1,pos-1]\)),然后我们就用单调栈把当前放的小于等于\(pos\)的值全部\(pop\)掉。对于后一半的我们就直接对于每个可以放的位置反复覆盖即可。

对于字典序最大的我们则就是前一半反复覆盖,后一半用单调栈维护,与字典序刚好相反。

代码实现如下

#include <set>
#include <map>
#include <deque>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <bitset>
#include <cstdio>
#include <string>
#include <vector>
#include <cassert>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std; typedef long long LL;
typedef pair<LL, LL> pLL;
typedef pair<LL, int> pLi;
typedef pair<int, LL> pil;;
typedef pair<int, int> pii;
typedef unsigned long long uLL; #define lson rt<<1
#define rson rt<<1|1
#define lowbit(x) x&(-x)
#define name2str(name) (#name)
#define bug printf("*********\n")
#define debug(x) cout<<#x"=["<<x<<"]" <<endl
#define FIN freopen("/home/dillonh/CLionProjects/Dillonh/in.txt","r",stdin)
#define IO ios::sync_with_stdio(false),cin.tie(0) const double eps = 1e-8;
const int mod = 998244353;
const int maxn = 3e5 + 7;
const double pi = acos(-1);
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3fLL; int n;
stack<int> st;
vector<int> vec, v;
int pos[maxn];
int a[maxn], dp[maxn], ans1[maxn], ans2[maxn]; int main() {
#ifndef ONLINE_JUDGE
FIN;
#endif
while(~scanf("%d", &n)) {
memset(dp, inf, sizeof(dp));
dp[0] = 0;
for(int i = 1; i <= n; ++i) {
scanf("%d", &a[i]);
ans1[i] = ans2[i] = 0;
pos[i] = inf;
ans1[i] = lower_bound(dp + 1, dp + n + 1, a[i]) - dp;
dp[ans1[i]] = a[i];
}
memset(dp, inf, sizeof(dp));
dp[0] = 0;
for(int i = n; i >= 1; --i) {
ans2[i] = lower_bound(dp + 1, dp + n + 1, a[i]) - dp;
dp[ans2[i]] = a[i];
}
while(!st.empty()) st.pop();
int idx = 1, mx = ans1[1] + ans2[1];
for(int i = 2; i <= n; ++i) {
if(ans1[i] + ans2[i] > mx) {
idx = i;
mx = ans1[i] + ans2[i];
}
}
pos[ans1[idx]] = a[idx];
for(int i = idx - 1; i >= 1; --i) {
if(ans1[i] >= ans1[idx]) continue;
if(pos[ans1[i]+1] <= a[i]) continue;
while(!st.empty() && ans1[i] >= ans1[st.top()]) {
pos[ans1[st.top()]] = inf;
st.pop();
}
st.push(i);
pos[ans1[i]] = a[i];
}
vec.clear();
while(!st.empty()) {
vec.push_back(st.top());
st.pop();
}
vec.push_back(idx);
int las = idx;
for(int i = idx + 1; i <= n; ++i) {
if(ans2[i] == ans2[las] - 1 && a[i] < a[las]) {
vec.push_back(i);
las = i;
}
}
int flag = 0;
for(auto x:vec) {
if(flag) printf(" ");
flag = 1;
printf("%d", x);
}
printf("\n"); vec.clear();
idx = 1, mx = ans1[1] + ans2[1];
for(int i = 2; i <= n; ++i) {
if(ans1[i] + ans2[i] >= mx) {
idx = i;
mx = ans1[i] + ans2[i];
}
}
las = idx;
vec.push_back(idx);
for(int i = idx - 1; i >= 1; --i) {
if(ans1[i] == ans1[las] - 1 && a[i] < a[las]) {
vec.push_back(i);
las = i;
}
}
reverse(vec.begin(), vec.end());
for(int i = 1; i<= n; ++i) pos[i] = inf;
pos[ans2[idx]] = a[idx];
while(!st.empty()) st.pop();
for(int i = idx + 1; i <= n; ++i) {
if(ans2[i] > ans2[idx]) continue;
if(a[i] >= pos[ans2[i]+1]) continue;
while(!st.empty() && ans2[i] >= ans2[st.top()]) {
pos[ans2[st.top()]] = inf;
st.pop();
}
st.push(i);
pos[ans2[st.top()]] = a[i];
}
v.clear();
while(!st.empty()) {
v.push_back(st.top());
st.pop();
}
reverse(v.begin(), v.end());
flag = 0;
for(auto x:vec) {
if(flag) printf(" ");
flag = 1;
printf("%d", x);
}
for(auto x:v) {
if(flag) printf(" ");
flag = 1;
printf("%d", x);
}
printf("\n");
}
return 0;
}

2019年杭电多校第二场 1002题Beauty Of Unimodal Sequence(LIS+单调栈)的更多相关文章

  1. 2019年杭电多校第二场 1008题Harmonious Army(HDU6598+最小割+建图)

    题目链接 传送门 题意 有\(n\)个士兵,要你给他们分配职业.有\(m\)对关系,对于某一对关系\(u,v\),如果同为勇士则总能力增加\(a\),同法师则增加\(c\),一个勇士一个法师增加\(\ ...

  2. 2019年杭电多校第二场 1012题Longest Subarray(HDU6602+线段树)

    题目链接 传送门 题意 要你找一个最长的区间使得区间内每一个数出现次数都大于等于\(K\). 思路 我们通过固定右端点考虑每个左端点的情况. 首先对于每个位置,我们用线段树来维护它作为\(C\)种元素 ...

  3. 2019年杭电多校第一场 1002题Operation(HDU6579+线性基)

    题目链接 传送门 题意 初始时有\(n\)个数,现在有\(q\)次操作: 查询\([l,r]\)内选择一些数使得异或和最大: 在末尾加入一个数. 题目强制在线. 思路 对于\(i\)我们记录\([1, ...

  4. Rikka with Travels(2019年杭电多校第九场07题+HDU6686+树形dp)

    目录 题目链接 题意 思路 代码 题目链接 传送门 题意 定义\(L(a,b)\)为结点\(a\)到结点\(b\)的路径上的结点数,问有种\(pair(L(a,b),L(c,d))\)取值,其中结点\ ...

  5. 2019年杭电多校第一场 1009题String(HDU6586+模拟+单调栈)

    题目链接 传送门 题意 给你一个字符串,要你构造一个长为\(k\)的子串使得每个字母出现的次数在\([L_i,R_i](0\leq i\leq26)\)间且字典序最小. 思路 做这种题目就是要保持思路 ...

  6. 2019年杭电多校第一场 1004题Vacation(HDU6581+数学)

    题目链接 传送门 题意 有\(n+1\)辆车要过红绿灯,告诉你车的长度.与红绿灯的起点(题目假设红绿灯始终为绿).车的最大速度,问你第\(0\)辆车(距离最远)车头到达红绿灯起点的时间是多少(每辆车最 ...

  7. 2019年牛客多校第二场 H题Second Large Rectangle

    题目链接 传送门 题意 求在\(n\times m\)的\(01\)子矩阵中找出面积第二大的内部全是\(1\)的子矩阵的面积大小. 思路 处理出每个位置往左连续有多少个\(1\),然后对每一列跑单调栈 ...

  8. 2019杭电多校第二场hdu6601 Keen On Everything But Triangle

    Keen On Everything But Triangle 题目传送门 解题思路 利用主席树求区间第k小,先求区间内最大的值,再求第二大,第三大--直到找到连续的三个数可以构成一个三角形.因为对于 ...

  9. 2019杭电多校第二场hdu6602 Longest Subarray(线段树)

    Longest Subarray 题目传送门 解题思路 本题求一个最大的子区间,满足区间内的数字要么出现次数大于等于k次,要么没出现过.给定区间内的数字范围是1~c. 如果r为右边界,对于一种数字x, ...

随机推荐

  1. 灵魂拷问:Java对象的内存分配过程是如何保证线程安全的?(阿里面试)

    JVM内存结构,是很重要的知识,相信每一个静心准备过面试的程序员都可以清楚的把堆.栈.方法区等介绍的比较清楚. 上图,是一张在作者根据<Java虚拟机规范(Java SE 8)>中描述的J ...

  2. 【RS】Wide & Deep Learning for Recommender Systems - 广泛和深度学习的推荐系统

    [论文标题]Wide & Deep Learning for Recommender Systems (DLRS'16) [论文作者] Heng-Tze Cheng, Levent Koc, ...

  3. List Map Set的线程安全

    常见的ArrayList  LinkedList  HashMap TreeMap LinkedHashMap HashSet TreeSet LinkedHashSet 都是线程不安全的.如果要使用 ...

  4. javascript的立即执行函数

    在javascript中有引入立即执行函数的概念,那么什么是立即执行函数呢?立即执行函数又是怎么写的呢?立即执行函数与普通函数有什么区别呢? 先来看看一般的函数: function a(){ var ...

  5. Spring boot + mybatis + dubbo + zookeeper + mysql + mybatis-generator 一个小demo

    代码的链接地址:https://gitee.com/frostGG/springbooo_dubbo_demo.git 1.项目的目录经构: 介绍: 这一个项目,用的是阿里的dubbo,和zookee ...

  6. .Net 如何使用Nlog

    NLog是一个简单灵活的.NET日志记录类库,NLog的API非常类似于log4net,且配置方式非常简单.通过使用NLog,我们可以在任何一种.NET语言中输出带有上下文的调试信息,根据项目需求配置 ...

  7. 删除排序链表中的重复元素II --链表

    题目 给定一个排序链表,删除所有含有重复数字的节点,只保留原始链表中 没有重复出现 的数字. 示例1 输入: ->->->->->-> 输出: ->-> ...

  8. 【题解】Luogu P5301 [GXOI/GZOI2019]宝牌一大堆

    原题传送门 首先先要学会麻将,然后会发现就是一个暴力dp,分三种情况考虑: 1.非七对子国士无双,设\(dp_{i,j,k,a,b}\)表示看到了第\(i\)种牌,一共有\(j\)个\(i-1\)开头 ...

  9. Mysql系列(二)—— Mysql支持的数据类型

    Mysql版本众多,每个版本支持的数据类型繁多且不一样,本篇文章中主要基于MySQL Community Server 5.7.22介绍常用的数据类型,包括其特点以及区别. 一.数据类型 正确的定义表 ...

  10. 入门-windows下安装ETH挖矿

    对刚入门的区块链开发者来说,刚开始可以在windows本地搭建私有链,便于操作,毕竟,要想真正挖到币还是有难度的,下面以ETH为例,在windows环境下安装并实现挖矿. 步骤一.安装geth环境.下 ...