题目链接

传送门

思路

首先我们对\(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;
}

最新文章

  1. js sort() reverse()
  2. rdesktop的使用方法
  3. C++快速入门系列教程
  4. seajs模块化作用理解(一句话)
  5. IdentityHashMap的使用场景
  6. FZU 1649 Prime number or not米勒拉宾大素数判定方法。
  7. Qt之事件系统
  8. dhtmlxScheduler日历日程控件包括天视图,周视图,月视图,年视图和日程表视图
  9. HTML xmlns
  10. Vijos p1002 过河 离散化距离+区间DP
  11. 201621123057 《Java程序设计》第4周学习总结
  12. c# &amp;sqlserver
  13. 微信小程序—如何获取用户输入文本框的值
  14. Codeforces1101G (Zero XOR Subset)-less 【线性基】【贪心】
  15. for...in的改进版for...of
  16. The import * cannot be resolved
  17. Ubuntu 安装微信
  18. 快速创建一个 Servlet 项目(2)
  19. 回车符与换行符问题——C语言
  20. java-信息安全(一)-BASE64,MD5,SHA,HMAC,RIPEMD算法

热门文章

  1. 【Gamma】PhyLab 测试报告
  2. leetcode-19:给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。
  3. 【2019年05月21日】A股ROE最高排名
  4. Spring JDBC最佳实践(3)
  5. mysql 添加注释
  6. TreeMap源码分析1
  7. Vue ----------- 了解, 展示json 数据
  8. myeclipse导入项目中文乱码怎么解决教程
  9. webbrowser实现一个进程一个代理的办法
  10. (原创)对比组态软件,使用C#开发的服务器和客户端软件的优势