[题解]SP57 SUPPER - Supernumbers in a permutation
思路
如果 在某一个最长上升子序列中,那么,这个最长上升子序列一定是形如 的。
发现 ,那么以 结尾的一串一定是一个最长上升子序列,以 开头的一定也是一个最长上升子序列。
那么我们跑两次 LIS,求出以 结尾的 LIS,与以 开头 的 LIS,分别用 表示。
对于一个可行的 一定有 ,其中 表示 LIS 的长度。
Code
#include <bits/stdc++.h>
#define re register
using namespace std;
const int N = 1e5 + 10,inf = 1e9 + 10;
int n;
int arr[N];
int q[2][N],dp[2][N];
inline int read(){
int r = 0,w = 1;
char c = getchar();
while (c < '0' || c > '9'){
if (c == '-') w = -1;
if (c == EOF) exit(0);
c = getchar();
}
while (c >= '0' && c <= '9'){
r = (r << 3) + (r << 1) + (c ^ 48);
c = getchar();
}
return r * w;
}
inline void solve(){
memset(q,0,sizeof(q));
memset(dp,0,sizeof(dp));
q[1][0] = inf;
vector<int> v;
int ans1 = 0,ans2 = 0;
n = read();
for (re int i = 1;i <= n;i++) arr[i] = read();
for (re int i = 1;i <= n;i++){
int id = lower_bound(q[0] + 1,q[0] + ans1 + 1,arr[i]) - q[0];
q[0][id] = arr[i];
dp[0][i] = id;
ans1 = max(ans1,id);
}
for (re int i = n;i;i--){
if (arr[i] < q[1][ans2]){
dp[1][i] = ++ans2;
q[1][ans2] = arr[i];
}
else{
int l = 1,r = ans2;
while (l < r){
int mid = l + r >> 1;
if (q[1][mid] <= arr[i]) r = mid;
else l = mid + 1;
}
q[1][l] = arr[i];
dp[1][i] = l;
ans2 = max(ans2,l);
}
}
for (re int i = 1;i <= n;i++){
if (dp[0][i] + dp[1][i] - 1 == ans1) v.push_back(arr[i]);
}
sort(v.begin(),v.end());
printf("%d\n",(int)(v.size()));
for (auto x:v) printf("%d ",x);
puts("");
}
int main(){
while (1) solve();
return 0;
}
作者:WaterSun
出处:https://www.cnblogs.com/WaterSun/p/18268811
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
分类:
题解
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】