题目链接

传送门

思路

首先我们对\(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. nmap简单使用方法

    1.作用扫描整个网络的主机服务状态和存活优点,快速,准确,效率高2.nmap 选项 Usage: nmap [Scan Type(s)] [Options] {target specification ...

  2. Executor多线程框架

    啥都别说了,上代码: import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; impor ...

  3. python的值传递与引用传递

    首先还是应该科普下函数参数传递机制,传值和传引用是什么意思? 函数参数传递机制问题在本质上是调用函数(过程)和被调用函数(过程)在调用发生时进行通信的方法问题.基本的参数传递机制有两种:值传递和引用传 ...

  4. Angular Material

    Angular Material 的设计之美   Ng-Matero 0.3 已发布,新增 module schematic 以及 page schematic,详见 README 前言 Angula ...

  5. Android.mk基础

    1.前言 Android.mk用于向编译系统描述源文件和共享库,它实际上是编译系统解析一次或多次的微小GNU makefile片段.它的语法支持将源文件分组为模块,模块是静态库.共享库或独立的可执行文 ...

  6. influx db

    1.查看数据库中的tag keys:     如果需要查看field的直接改 > show tag keys on test; name: garage_pc_overviewtagKey--- ...

  7. vs2015 出现的错误lnk:200:-main已在ax.obj中定义

    原因是:一个项目里只能有一个main函数, 如果出现 error:LNK200 的错误,那么需要检查你是不是有两个源代码文件中都定义了main函数. 解决方案:  把其中的一个main函数删掉

  8. 离线方式快速安装python模块以及相关依赖模块

    一般公司的服务器都是和外网隔离的,这个如果没有内部pip源的话,想要安装python的模块就需要去python官网一个一个下载依赖模块的包,然后逐个安装,这样做非常耗时间. 我们今天用的办法就是现在我 ...

  9. Zookeeper学习笔记:简单注册中心

    zookeeper可以作为微服务注册中心,spring cloud也提供了zookeeper注册中心的支持. 本文介绍如何实现一个简单的zookeeper注册中心,主要的实现方式: n个服务提供者对外 ...

  10. MySQL之查询篇(三)

    一:查询 1.创建数据库,数据表 -- 创建数据库 create database python_test_1 charset=utf8; -- 使用数据库 use python_test_1; -- ...